..title      > Una introducción a la programación en Emacs Lisp
..subtitle   > Revisada la tercera edición
..author     > Robert J. Chassell
..translator > David Arroyo Menéndez
..translator > nasciiboy
..lang       > es
..style      > worg-data/worg.css
..options    > fancyCode toc


Esto es una @e{Introducción a la Programación en Emacs Lisp}, para personas que
no son programadoras.

Traducido desde la edición 3.10

Copyright ® 1990–1995, 1997, 2001–2013 Free Software Foundation, Inc.

Permission is granted to copy, distribute and/or modify this document under
the terms of the GNU Free Documentation License, Version 1.3 or any later
version published by the Free Software Foundation; there being no Invariant
Section, with the Front-Cover Texts being “A GNU Manual”, and with the
Back-Cover Texts as in (a) below. A copy of the license is included in the
section entitled “GNU Free Documentation License”.

(a) The FSF's Back-Cover Text is: “You have the freedom to copy and modify
this GNU manual. Buying copies from the FSF supports it in developing GNU
and promoting software freedom.”

* Prefacio

  La mayoría del entorno integrado GNU Emacs está escrito en el lenguaje de
  programación llamado Emacs Lisp. El código escrito en este lenguaje de
  programación es el software––el conjunto de instrucciones––que le indican al
  ordenador qué hacer cuando se le dan comandos. Emacs está diseñado de forma
  que se pueda escribir nuevo código en Emacs Lisp e instalarlo fácilmente como
  una extensión al editor.

  (GNU Emacs se define muchas veces como un “editor extensible”, pero hace
  mucho más que proporcionar capacidad de edición. Es mejor referirse a Emacs
  como un “entorno de computación extensible”. Sin embargo, esa frase es un
  poco pretenciosa. Es más fácil referirse a Emacs simplemente como un
  editor. De hecho, cada cosa que se hace en Emacs––encontrar la fecha Maya y
  fases de la luna, simplificar polinomios, depurar código, administrar
  ficheros, leer cartas, escribir libros––todas estas actividades son maneras
  de editar en un sentido mas amplio de la palabra.)

  Aunque Emacs Lisp normalmente se asocia solo con Emacs, es un lenguaje de
  programación completo. Se puede usar Emacs Lisp del mismo modo que con
  cualquier otro lenguaje de programación.

  Quizás quieras entender la programación; quizás quieras extender Emacs; o
  tal vez quieras convertirte en un programador. Esta introducción a Emacs Lisp está
  diseñada para que empieces: para guiarte en el aprendizaje de los fundamentos
  de la programación y, lo que es más importante, para mostrarte como puedes
  aprender a ir mas más allá.

** Sobre la lectura de este texto

   A lo largo de este documento, verás pequeños programas de ejemplo que se
   pueden ejecutar dentro de Emacs. Si lees este documento dentro de GNU Emacs,
   puedes ejecutar los programas tal y como aparecen. (Esto es fácil de hacer y
   se explica cuando se presentan los ejemplos). Alternativamente, puedes leer
   esta introducción como un libro impreso mientras se está sentando frente a un
   ordenador ejecutando Emacs. (Esto es lo que me gusta hacer; me gustan los
   libros impresos.) Si no tienes un Emacs funcionando a tu lado, todavía
   puedes leer este libro, pero en este caso, lo mejor es tratarlo como una
   novela, o como una guía de viaje a un país que aún no visitas: interesante,
   pero no es lo mismo que estar allí.

   Gran parte de esta introducción esta dedicada a recorridos o visitas guiadas
   del código usado en GNU Emacs. Estos recorridos están diseñados para dos
   propósitos: primero, para que te familiarices con el código de trabajo real
   (código que se usa cada día); y, segundo, para que te familiarices con el
   funcionamiento de Emacs. Es interesante ver cómo se implementa un entorno de
   trabajo completamente operativo. Ademas, espero que adquieras el hábito de
   navegar a través del código fuente. Puedes aprender mucho comparando código
   de otros con el propio y extraer nuevas ideas. Tener GNU Emacs es como tener
   la cueva del dragón de los tesoros.

   Además de aprender sobre Emacs como editor y Emacs Lisp como lenguaje de
   programación, los ejemplos y visitas guiadas te darán una oportunidad para
   familiarizarte con Emacs como entorno de programación Lisp. GNU Emacs
   soporta programación y provee herramientas que llegaras a sentirte comodo
   usando, como @k{M-.} (el atajo que invoca el comando @c{find-tag}). También
   aprenderas sobre los búfers y otros objetos que forman parte del entorno.
   Aprender estas caracteristicas de Emacs es como aprender nuevas rutas
   alrededor de tu ciudad natal.

   Finalmente, espero poder transmitirte algunas habilidades para utilizar
   Emacs con el fin de aprender aspectos de programación que no conoces. Con
   frecuencia se puede usar Emacs como ayuda para entender un rompecabezas o
   para encontrar la manera de hacer algo nuevo. Este auto-descubrimiento no
   es solo un placer, también es una ventaja.

** Para quien está escrito esto

   Este texto está escrito como una introducción elemental para personas que no
   son programadoras. Si eres es un programador, es posible que no estes
   satisfecho con este manual. La razón es que un programador puede tener que
   convertirse en experto leyendo manuales de referencia y este texto no está
   organizado como un manual de referencia.

   Un programador experto que revisó este texto me dijo:

   ..quote >
     Prefiero aprender desde manuales de referencia. Me “zambullo” en cada
     párrafo y “subo a tomar aire” entre párrafos.

     Cuando llego al fin de un párrafo, asumo que este asunto está hecho,
     terminado, que sé todo lo que necesito (con la posible excepción del caso
     en que el siguiente párrafo empiece a hablar de ello con más detalle). Espero
     que un manual de referencia bien escrito no tenga mucha redundancia, y que
     tenga excelentes indicadores del (unico) lugar donde está la información
     que quiero.
   < quote..

   ¡Esta introducción no está escrita para esta persona!

   En primer lugar, intento decir cada cosa al menos tres veces: primero, para
   introducirlo; segundo, para mostrarlo en contexto; y tercero, para mostrarlo
   en un contexto diferente, o revisarlo.

   En segundo lugar, casi nunca pongo toda la información sobre un tema en un
   solo lugar, y mucho menos en un párrafo. A mi manera de pensar, eso impone
   una carga bastante pesada al lector. En cambio, trato de explicar solo lo
   que necesitas saber en ese momento. (Algunas veces incluyo una pequeña
   información extra, para que no haya sorpresas más tarde cuando la información
   adicional sea presentada formalmente.)

   Cuando leas este texto, no se esperes aprender todo la primera vez.
   Frecuentemente, solo necesitas, por asi decirlo, un ‘asentir con la cabeza’
   en alguno de los articulos mencionados. Mi esperanza es haber estructurado el
   texto y dar suficientes pistas para indicar lo que es importante y
   te concentres en ello.

   Necesitaras “sumergirte” en algunos párrafos; no hay otro modo de
   leerlos. Pero he intentado reducir el número de esos párrafos. Este libro
   pretende ser como una colina accesible, mas que una montaña abrumadora.

   Esta introducción a la @e{Programación en Emacs Lisp} tiene un documento
   complementario. @e{El Manual de Referencia de GNU Emacs Lisp}. El manual de
   referencia tiene más detalles que esta introducción. En el manual de
   referencia, toda la información sobre un tema se concentra en un solo
   lugar. Deberias recurrir a el si eres como el programador citado
   anteriormente. Y, por supuesto, después de haber leido esta @e{Introducción},
   encontraras el @e{Manual de Referencia} util cuando escribas tus propios
   programas.

** Historia de Lisp

   Lisp fué originariamente desarrollado a finales de los años 50 en el
   Instituto Tecnológico de Massachusetts para la investigacion en inteligencia
   artificial. El gran poder del lenguaje Lisp lo hace superior también para
   otros propósitos, como la escritura de comandos de edición y entornos
   integrados.

   GNU Emacs Lisp está fuertemente inspirado en Maclisp, que fue escrito en el
   MIT en la decada de 1960. Está en cierto modo inspirado en Common Lisp, que
   se convirtio en un estándar en los 80. Sin embargo, Emacs Lisp es mucho más
   simple que Common Lisp. (La distribución estándar de Emacs contiene un
   fichero de extensiones opcional, @f{cl.el}, que añade muchas caracteristicas
   de Common Lisp a Emacs Lisp.)

** Nota para los principiantes

   Si no conoces GNU Emacs, todavia puedes leer este documento
   provechosamente. Sin embargo, te recomiendo que aprendas Emacs, al menos
   aprender a moverte alrededor de la pantalla del ordenador. Puedes aprender
   por ti mismo como usar Emacs con el tutorial incorporado. Para usarlo,
   escribe @k{C-h t}. (Esto significa que debes presionar la tecla @k{CTRL}
   y la @k{h} al mismo tiempo, y luego presionar y soltar @k{t}).

   Ademas, a menudo me refiero a uno de los comandos estándar de Emacs listando
   las teclas que se presionan para invocar el comando y, luego dando el nombre
   del comando entre paréntesis, asi: @k{M-C-\} (@c{indent-region}). Esto
   significa invocar el comando @c{indent-region} presionando @k{M-C-\}. (Puedes,
   Si lo deseas, cambiar las teclas que se presionan para invocar el comando;
   esto se denomina @:{rebinding}. Consulta la Sección @l{#Mapas de teclado}.)
   La abreviatura @k{M-C-\} significa que debes presionar la tecla @k{META},
   @k{CTRL}, y @k{\} al mismo tiempo. (En muchos teclados modernos la tecla
   @k{META} se llama @k{ALT}.)  Algunas veces una combinación como esta
   se llama un @e{acorde de teclas}, puesto que es similar a tocar un acorde en un
   piano. Si el teclado no tiene una tecla @k{META}, en su lugar se usa la tecla
   @k{ESC} como prefijo. En este caso @k{M-C-\} significa que se presiona y
   libera @k{ESC} y luego se presionan la tecla @k{CTRL} y la tecla @k{\} al mismo
   tiempo. Pero normalmente @k{M-C-\} significa presionar la tecla @k{CTRL}
   junto a la tecla que está marcada como @k{ALT} y, al mismo tiempo, presionar
   la tecla @k{\}.

   Además de pulsar una sola combinación de teclas, puedes prefijar lo que
   escribes con @k{C-u}, que se llama el ‘argumento universal’. El atajo @k{C-u}
   pasa un argumento al siguiente comando. Por lo tanto, para indentar una
   región de texto plano por 6 espacios, marca la región, y lugo presiona @k{C-u
   6 M-C-\}. (Si no se especifica un número, Emacs pasa el número 4 al comando o
   ejecuta el comando de forma diferente a como lo haria de otro modo). Consulta
   la Sección @l{emacs.html#Arguments<>Argumentos
   Numéricos} en @e{El Manual de GNU Emacs}.

   Si estás leyendo esto en Info usando GNU Emacs, puedes avanzar a través de
   todo este documento presionando la barra espaciadora, @k{SPC}. (Para
   aprender acerca de Info, presiona @k{C-h i} y luego selecciona Info.)

   Una nota sobre terminología: cuando uso la palabra Lisp sola, con frecuencia
   me estoy refiriendo a los diversos dialectos de Lisp en general, pero cuando
   hablo de Emacs Lisp, me estoy refiriendo a GNU Emacs Lisp en particular.

** Agradecimientos

   Estoy agradecido a todos los que me ayudaron con este libro. Mi
   especial agradecimiento a Jim Blandy, Noah Friedman, Jim Kingdon, Roland
   McGrath, Frank Ritter, Randy Smith, Richard M. Stallman, y Melissa
   Weisshaus. Gracias también a Philip Johnson y David Stampe por su paciente
   aliento. Mis errores son míos.

   ..right >
     Robert J. Chassell @l{mailto:bob@@gnu.org}

* Procesamiento de listas

  Para el ojo inexperto, Lisp es un lenguaje de programación extraño. En
  código Lisp hay paréntesis por todas partes. Algunas personas incluso
  afirman que el nombre signfica ‘Lots of Isolated Silly Parentheses’
  (‘Montones de Paréntesis Aislados Estúpidos’). Pero el reclamo es
  injustificado. Lisp significa LISt Processing, y el lenguaje de
  programación maneja @e{listas} (y listas de listas) poniéndolas entre
  paréntesis. Los paréntesis marcan los límites de la lista. Algunas veces
  una lista va precedida por un apóstrofe simple o una marca de cita,
  @'{'}@n{1}. Las listas son el fundamento de Lisp.

** Listas Lisp

   En Lisp, una lista tiene el siguiente aspecto: @c{'(rosa violeta margarita
   tulipan)}.  Esta lista es precedida por una comilla. Bien, podría estar
   escrita de la siguiende manera, que se parece mas al tipo de lista con la que
   probablemente estes familiarizado:

   ..src > elisp
     '(rosa
       violeta
       margarita
       tulipan)
   < src..

   Los elementos de esta lista son los nombres de 4 flores diferentes,
   separados por espacios en blanco y rodeados de paréntesis, como flores en
   un campo con un muro de piedras a su alrededor.

   Las listas también pueden tener números, como en esta lista: @c{(+
   2 2)}. Esta lista tiene un signo más, @'{+}, seguido por dos @'{2}, cada
   uno separado por espacios en blanco.

   En Lisp, tanto datos como programas se representan de la misma manera; es
   decir, son a la vez listas de palabras, números, u otras listas, separadas
   por espacios en blanco y rodeadas de paréntesis. (Puesto que un programa se
   parece a los datos, un programa puede servir fácilmente como datos para
   otros; esta es un caracteristica muy poderosa de Lisp.)  (A proposito, estas
   dos marcas de paréntesis @e{no} son listas Lisp, porque contienen @'{;} y
   @'{.} como signos de puntuación.)

   Aquí hay otra lista, esta vez con una lista dentro de ella:

   ..src > elisp
     '(esta lista tiene (una lista dentro de ella))
   < src..

   Los componentes de esta lista son las palabras @'c{esta}, @'c{lista},
   @'c{tiene}, y la lista @'c{(una lista dentro de ella)}. La lista interior se
   construye con las palabras @'c{una}, @'c{lista}, @'c{dentro}, @'c{de},
   @'c{ella}.

*** Átomos Lisp

    En Lisp, lo que hemos estado llamando palabras son en realidad
    @:{átomos}. Este término proviene del significado historico de la palabra
    átomo, que significa ‘indivisible’. En lo que a Lisp concierne, las palabras
    que hemos estado usando en las listas no se pueden dividir en partes mas
    pequeñas, sin perder su significado dentro del programa; lo mismo ocurre con
    números y símbolos de un caracterer como @'{+}. Por otro lado, a diferencia
    de un átomo antiguo, una lista puede dividirse en partes. Consulta la seccion
    @l(#@c{car}, @c{cdr}, @c{cons}: Funciones fundamentales).

    En una lista, los átomos se separan unos de otros por espacios en blanco.
    Pueden estar justo al lado de un paréntesis.

    Técnicamente hablando, una lista en Lisp consiste en paréntesis que rodean
    átomos separados por espacios en blanco o alrededor de otras lista o
    alrededor de ambos átomos y otras listas. Una lista puede tener solo un
    átomo o no tener absolutamente nada en ella. Una lista con nada dentro se
    ve así: @c{()}, y se llama @:{lista vacía}. A diferencia de cualquier otra
    cosa, una lista vacía es tanto un átomo, como una lista al mismo tiempo.

    La representación impresa de átomos y listas se llaman @:{expresiones
    simbólicas} o, más concisamente, @:{expresiones-s}. La palabra @:{expresión}
    por sí misma puede referirse o bien a la representación impresa, o al átomo o
    a la lista tal como se encuentra internamente en el ordenador. Con
    frecuencia, la gente usan el término @:{expresión} indiscriminadamente.
    (Ademas, en muchos textos, la palabra @:{forma} se usa como un sinónimo de
    expresión.)

    Por cierto, los átomos que componen nuestro universo fueron nombrados asi
    cuando se pensaba que eran indivisibles; pero se ha descubierto que los
    átomos fisicos no son indivisibles. Las partes pueden dividir un átomo o
    puede fisionarse en 2 partes de igual tamaño. Los átomos físicos se
    nombraron prematuramente, antes de que su verdadera naturaleza fuese
    encontrada. En Lisp, ciertos tipos de átomos, como un array, pueden ser
    separados en partes; pero el mecanismo de hacer esto es diferente del
    mecanismo para dividir una lista. En lo que se refiere a las operaciones de
    lista, los átomos de una lista son indivisibles.

    Al igual que en el español, el significado de las letras que componen un
    átomo Lisp difieren del significado de las letras compuestas como una
    palabra. Por ejemplo, la expresión @'{ay}, es completamente diferente de las
    dos palabras @'{a}, e @'{y}.

    Hay muchos tipos de átomos en la naturaleza, pero solo unos pocos en Lisp:
    por ejemplo, los @:{números}, como 37, 511, o 1729, y los @:{símbolos}, como
    @'{+}, @'{foo}, o @'{forward-line}. Las palabras que hemos listado en los
    ejemplos anteriores son todos símbolos. En las conversaciones cotidianas de
    Lisp, la palabra “átomo” no se usa con frecuencia, porque los programadores
    normalmente intentan ser más específicos acerca del tipo de átomo que están
    tratando. La programación Lisp es mayormente sobre símbolos (y algunas veces
    números) dentro de listas. (De ese modo, tres palabras rodeadas de paréntesis son
    una lista apropiada en Lisp, ya que consiste de átomos, que en este caso son
    símbolos, separados por espacios en blanco y encerrados entre paréntesis, sin
    ninguna puntuacion ajena a Lisp.)

    El texto entre comillas––incluso oraciones o párrafos––son también un átomo.
    Aquí hay un ejemplo:

    ..src > elisp
      '(esta lista incluye "texto entre comillas.")
    < src..

    En Lisp, todo el texto entre comillas, incluyendo la marca de puntuación y los
    espacios en blanco, son un unico átomo. Este tipo de átomo se llama
    @:{string} @%i(cadena), por ‘cadena de caracteres’) y es el tipo de cosa que
    se utiliza para los mensajes que un ordenador puede imprimir para que los
    lea un humano. Las cadenas son un tipo de átomo diferente a los números, o
    símbolos y se usan de manera diferente.

*** Espacios en blanco en las listas

    La cantidad de espacios en blanco en una lista no importa. Desde el punto
    de vista del lenguaje Lisp,

    ..src > elisp
      '(esta lista
         se ve asi)
    < src..

    es exactamente lo mismo que esto:

    ..src > elisp
      '(esta lista se ve asi)
    < src..

    Ambos ejemplos muestran lo que para Lisp es la misma lista, la lista compuesta
    por los símbolos @'c{esta}, @'c{lista}, @'c{se}, @'c{ve}, y @'c{asi} en ese orden.

    Los espacios en blanco adicionales y los saltos de línea están diseñados
    para crear una lista más legible para los humanos. Cuando Lisp lee la
    expresión, se deshace de todos los espacios en blanco adicionales (pero necesita tener
    al menos un espacio entre los átomos para poder distinguirlos.)

    Por extraño que parezca, los ejemplos que hemos visto cubren casi todos los
    aspectos de las listas de Lisp. Cualquier otra lista en Lisp se ve más o
    menos igual a uno de estos ejemplos, excepto que la lista puede ser más
    larga y compleja. En resumen, una lista está entre paréntesis, una cadena
    entre comillas, un símbolo se parece a una palabra, y un número a un
    número. (Para ciertas situaciones, es pueden utilizar corchetes, puntos y
    otros caracteres especiales; sin embargo; iremos bastante lejos sin ellos.)

*** GNU Emacs te ayuda a escribir listas

    Cuando se escribe una expresión Lisp en GNU Emacs usando el modo de
    Interacción Lisp o el modo Emacs Lisp, están disponibles varios comandos
    para formatear la expresión Lisp, de modo que sea fácil de leer. Por
    ejemplo, presionando la tecla @k{TAB} automáticamente se indenta la línea
    donde se encuentra el cursor a la cantidad correcta. Un comando para indentar
    apropiadamente el código en una región suele vincularse a @k{M-C-\}. La
    indentación está diseñada de modo que se pueda ver qué elementos pertenecen a
    cada lista––los elementos de una sublista están más indentados que los
    elementos de la lista adjunta.

    Además, al escribir un paréntesis de cierre, Emacs mueve el cursor
    momentáneamente hacia el parentesis de apertura correspondiente, para que
    puedas ver cual es. Esto es muy útil, ya que cada lista que escribas en
    Lisp debe tener su paréntesis de cierre que coincida con su paréntesis de
    apertura. (Consulta la Seccion @l{emacs.html#Major
    Modes<>Modos Mayores} en @e{El Manual de GNU Emacs}, para más información
    sobre los modos de Emacs.)

** Ejecutar un programa

   Una lista en Lisp––cualquier lista––es un programa listo para ejecutarse. Si
   lo ejecutas (lo que la jerga Lisp llama @:{evaluar}), el ordenador hará una
   de tres cosas: nada excepto devolverte la lista misma; enviar un mensaje de
   error; o, tomar el primer símbolo en la lista como un comando para hacer
   alguna cosa. (¡Normalmente, por supuesto, es la última de estas tres cosas lo
   que realmente quieres!).

   El apóstrofe, @c{'}, que puse delante de algunas de las listas de ejemplo en
   las secciones anteriores se llama @:{quote} (citar); cuando precede a una
   lista, le dice a Lisp que no haga nada con la lista, mas que tomarla tal
   como está escrita. Pero si no hay una cita precediendo la lista, el primer
   elemento de la lista es especial: es un comando que el ordenador debe
   obedecer. (En Lisp, estos comandos se llaman @e{funciones}.) La lista @c[(+ 2
   2)] mostrada a continuación no tiene una cita delante de ella, por lo que
   Lisp comprende que @c{+} es una instrucción para hacer alguna cosa con el
   resto de la lista: sumar los números que siguen.

   Si estás leyendo esto dentro de GNU Emacs, aquí está como puedes evaluar
   tal lista: coloca tu cursor justo después del paréntesis derecho de la
   siguiente lista y presiona @k{C-x C-e}:

   ..src > elisp
     (+ 2 2)
   < src..

   Verás que el número @c{4} aparece en el área eco. (En la jerga, lo que
   acabas de hacer es “evaluar la lista.” El área de eco es la línea en la
   parte inferior de la pantalla que muestra o hace “eco” del texto.) Ahora
   intenta lo mismo con una lista con cita: coloca el cursor
   justo después de la siguiente lista y presiona @k{C-x C-e}:

   ..src > elisp
     '(esto es una lista citada)
   < src..

   Verás aparecer @c{(esto es una lista citada)} en el área eco.

   En ambos casos, lo que estás haciendo es dar un comando al programa dentro
   de GNU Emacs llamado @:{intérprete Lisp}––dando al intérprete un comando
   para evaluar la expresión. El nombre del intérprete Lisp viene de la
   palabra para la tarea realizada por un humano que viene con el significado de
   una expresión––quien lo “interpreta”.

   También puedes evaluar un átomo que no es parte de una lista––uno que no
   está rodeado por paréntesis; una vez mas, el intérprete Lisp traduce desde la
   expresión humanamente legible al lenguaje del ordenador. Pero antes de
   discutir esto (consulta la Seccion @l{#Variables}), veremos lo que hace
   intérprete de Lisp cuando cometes un el error.

** Generar un mensaje de error

   En parte para que no te preocupes si generas un mensaje de error de manera
   accidental, ahora daremos un comando al intérprete de Lisp que genera un
   mensaje de error.  Esta es una accion inofensiva; y de hecho, a menudo
   intentaremos generar mensajes de error de manera intencional. Una vez se entiende
   la jerga, los mensajes de error pueden ser informativos. En lugar de
   llamarse mensajes de “error”, deberían llamarse mensajes de “ayuda”. Son
   como señales para un viajero en un país extraño; descifrarlas puede ser
   dificil, pero una vez se comprenden, pueden señalar el camino.

   El mensaje de error es generado por un depurador de codigo incorporado dentro
   de GNU Emacs. Vamos a ‘entrar al depurador’. Para salir del depurador, presiona
   @c{q}.

   Lo que vamos a hacer es evaluar una lista que no tiene cita y que no tiene un
   comando con significado como primer elemento. Aquí hay una lista casi
   exactamente igual a la que acabamos de usar, pero sin la cita al inicio.
   Coloca el cursor a la derecha donde esta finaliza y presiona @k{C-x C-e}:

   ..src > elisp
     (esto es una lista sin cita)
   < src..

   Se abrirá una ventana @f{*Backtrace*} y deberias ver lo siguiente:

   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--Lisp error: (void-function esto)
       (esto es una lista sin cita)
       eval((esto es una lista sin cita) nil)
       eval-last-sexp-1(nil)
       eval-last-sexp(nil)
       call-interactively(eval-last-sexp nil nil)
       command-execute(eval-last-sexp)
     ---------- Buffer: *Backtrace* ----------
   < example..

   Tu cursor estará en esta ventana (es posible que tengas que esperar unos
   pocos segundos antes de que se haga visible). Para salir del depurador y
   hacer que su ventana desaparezca, presiona: @k(q)

   Por favor, ahora presiona @k{q}, para que puedas comprobar que se puede
   salir del depurador. A continuacion, presiona @k{C-x C-e} una vez mas para
   re-entrar.

   Basandonos en lo que ya sabemos, casi podemos leer este mensaje de error.

   Leyendo el búfer @f{*Backtrace*} desde abajo hacia arriba; dice lo que hizo
   Emacs. Cuando presionaste @k{C-x C-e}, se hiso una llamada interactiva al
   comando @c{eval-last-sexp}. @c{eval} es una abreviatura para ‘evaluar’ y
   @c{sexp} es una abreviatura para ‘expresión simbólica’. El comando significa
   ‘evalúa la última expresión simbólica’, que es la expresión inmediatamente
   anterior al cursor.

   Cada linea sobre esta cuenta lo que el intérprete Lisp evaluo a continuacion. La
   acción más reciente está en la parte superior. El búfer se llama
   @f{*Backtrace*} por que permite realizar un seguimiento de Emacs hacia atrás.

   En la parte superior del búfer @f{*Backtrace*}, verás la línea:

   ..example >
     Debugger entered--Lisp error: (void-function esto)
   < example..

   El intérprete Lisp intentó evaluar el primer átomo de la lista, la palabra
   @'{esto}. Es esta acción la que genero el mensaje de error @'{void-function
   esto}.

   El mensaje contiene las palabras @'{void-function} y @'{esto}.

   La palabra @'{function} @%i(función) fué mencionada antes. Es una palabra muy
   importante. Para nuestros propósitos, podemos definirla diciendo que una
   @:{función} es un conjunto de instrucciones para decirle al
   ordenador que haga alguna cosa.

   Ahora podemos empezar a entender el mensaje de error: @'{void-function
   esto}. La función (es decir, la palabra @'{esto}) no tiene una definición de
   ningun conjunto de instrucciones que el ordenador pueda realizar.

   La palabra ligeramente extraña, @'{void-function}, está diseñada para cubrir
   la forma en que Emacs Lisp lo implementa, que es cuando un símbolo no tiene
   una definición de función adjunta, el sitio que contiene la instruccion esta
   ‘vacio’ @%i(void).

   Por otro lado, ya que fuimos capaces de sumar 2 más 2 de manera exitosa,
   evaluando @c{(+ 2 2)}, se puede inferir que el símbolo @c{+} debe tener un
   conjunto de instrucciones que el ordenador ejecuta y estas instrucciones
   deben ser para sumar los números despues del @c{+}.

   Es posible evitar que Emacs entre en el depurador en casos como este. No se
   explicará cómo hacer esto aquí, pero mencionamos como se ve el resultado,
   porque puede que te encuentres con una situación similar si hay un error en
   algún código de Emacs que estes usando. En tales casos, solo verá una línea
   de mensaje de error; aparecera en el área de eco con el siguente aspecto:

   ..example >
     Symbol's function definition is void: esto
   < example..

   El mensaje desaparece tan pronto se presione una tecla, aunque sólo sea para
   mover el cursor.

   Conocemos el significado de la palabra @'{Symbol}. Se refiere al primer
   átomo de la lista, la palabra @'{esto}. La palabra @'{function} se refiere
   a las instrucciones que indican al ordenador que hacer. (Técnicamente, el
   símbolo le indica al ordenador donde encontrar las instrucciones, pero esta
   es una complicación que podemos ignorar por el momento.)

   El mensaje de error es comprensible: @'{La definición del símbolo
   está vacía: esto}. El símbolo (que es, la palabra @'{esto}) carece de
   instrucciones para que el ordenador las lleve a cabo.

** Nombres de símbolos y definiciones de funcion

   Podemos articular otra característica de Lisp basada en lo que hemos
   discutido hasta ahora––una característica importante: un símbolo, como @c{+},
   no es en sí mismo el conjunto de instrucciones que el ordenador lleva a cabo. En
   su lugar, el símbolo se utiliza, quizás temporalmente, como una forma de
   localizar la definición o conjunto de instrucciones. Lo que vemos es el
   nombre con el cual se pueden encontrar las instrucciones. Los nombres de las
   personas funcionan de la misma manera. Por ejemplo puedo ser referido como
   @'{Bob}; sin embargo, no soy las letras @'{B}, @'{o}, @'{b} pero soy, o fuí,
   conscientemente asociado con una forma de vida en particular. El nombre no soy
   yo, pero puede ser usado para referirse a mi.

   En Lisp, un conjunto de instrucciones puede ligarse a varios nombres. Por
   ejemplo, las instrucciones para sumar números se pueden ligar al símbolo
   @c{mas} asi como al símbolo @c{+} (y se encuentran en algunos dialectos de
   Lisp). Entre los humanos, puede referirse a @'{Robert} tan bien como @'{Bob} y
   con otras palabras también.

   Por otra parte, un símbolo solo puede estar ligado con una definicion de
   función a la vez. De lo contrario, el ordenador estaría confundido en cuanto a
   qué definición usar. Si este fuera el caso entre las gente, solo una persona
   en el mundo podría llamarse @'{Bob}. Sin embargo, la definición de función a
   la que el nombre hace referencia puede cambiarse fácilmente. (Consulta la
   Sección @l{#Instalar una Definición de Función}.)

   Ya que Emacs Lisp es extenso, se acostumbra nombrar los símbolos de una
   forma que identifique la parte de Emacs a la que pertenece la función. En
   consecuencia, todos los nombres de funciones relacionadas con Texinfo
   comienzan con @'c{texinfo-} y aquellas relacionadas con la lectura de correo
   empiezan con @'c{rmail-}.

** El intérprete Lisp

   Basado en lo que hemos visto, ahora podemos empezar a entender lo que hace el
   intéprete Lisp cuando le ordenamos que evalue una lista. Primero, examina si
   hay un símbolo de cita antes de la lista; si lo hay, el intérprete solo nos da
   la lista. Por otra parte, si no hay cita, el intéprete mira si el primer
   elemento de la lista tiene una definición de función. De lo contrario, el
   intérprete imprime un mensaje de error.

   Así es como funciona Lisp. Simple. Hay complicaciones añadidas a las que
   llegaremos en un minuto, pero estos son los fundamentos. Por supuesto, para
   escribir programas Lisp, se necesita saber como escribir definiciones de
   función y vincularlas a nombres, y como hacer esto sin confundirnos a
   nosotros mismos o al ordenador.

   Ahora, una primera complicación. Además de las listas, el intérprete Lisp
   puede evaluar un símbolo sin citar y que no tiene paréntesis en torno a el. El
   intérprete intentará determinar el valor del símbolo como una @:{variable}.
   Esta situación se describe en el apartado de las variables. (Consulta la Seccion
   @l{#Variables}.)

   La segunda complicación ocurre debido a que algunas funciones son inusuales y
   no funcionan de la manera habitual. Estas se llaman @:{formas especiales}
   @%i(special forms). Se utilizan para trabajos especiales, como definir una
   función, y no hay muchas de ellas. En los siguientes capítulos, se
   presentaran varias de las formas especiales más importantes.

   La tercera y ultima complicación es la siguiente: si la función que el
   intérprete Lisp está examinando no es una forma especial, y si es parte de
   una lista, el intérprete Lisp mira si la lista tiene una lista dentro de
   ella. Si existe una lista interna, el intérprete Lisp primero determina lo qué
   debe hacer con la lista interna, y luego trabaja en la lista externa. Si
   hay otra lista incrustada dentro de la lista interna, trabaja en esta
   primero, y así sucesivamente. Siempre se trabaja en la lista mas interna primero. El
   interprete trabaja primero en la lista más interana, para evaluar el
   resultado de esa lista. El resultado puede ser usado por la expresión
   entre paréntesis.

   Por lo demas, el intérprete trabaja de izquierda a derecha, de una expresión
   a la siguiente.

*** Codigo Compilado

    Otro aspecto de la interpretación: el intérprete Lisp es capaz de
    interpretar dos tipos de entidades: código humanamente legible, en el que
    nos centraremos exclusivamente, y código especialmente procesado, llamado
    @:{compilado}, que no es humanamente legible. El código compilado se
    ejecuta más rápido que el código legible humanamente.

    Tu puedes transformar código legible por humanos en código compilado
    ejecutando uno de los comandos de compilación como @c{byte-compile-file}.
    El código compilado se almacena normalmente en un fichero que finaliza
    con una extensión @f{.elc} en lugar de una extensión @f{.el}. Verás ambos
    tipos de ficheros en el directorio @f{emacs/lisp}; los ficheros para leer
    son aquellos con la extensión @f{.el}.

    Como una cuestión práctica, para hacer la mayoría de las cosas como
    personalizar o extender Emacs, no necesitas compilar codigo; y no
    comentare el asunto aquí. Consulta la Seccion @l{elisp.html#Byte
    Compilation<>Código Compilado} en @e(El Manual de Referencia de GNU
    Emacs Lisp), para una descripción completa de la compilacion de código.

** Evaluación

   Cuando el intérprete Lisp trabaja en una expresión, el término para la
   esa actividad se llama @:{evaluación}. Decimos que el intérprete ‘evalúa la
   expresión’. He usado este término varias veces antes. La palabra proviene
   de su uso en el lenguaje cotidiano, ‘para determinar el valor o la cantidad de;
   para evaluar’ segun el @e{Webster's New Collegiate Dictionary}.

   Después de evaluar una expresión, es muy probable que el intérprete Lisp
   @:{devuelva} el valor que el ordenador produce al ejecutar las instrucciones
   que encuentra en la definición de la función, o quizás se de por vencido con
   en esa función y produzca un mensaje de error. (El intérprete también puede
   quedarse colgado, por así decirlo, a una función diferente o puede intentar
   repetir continuamente lo que está haciendo por siempre en lo que se llama un
   ‘bucle infinito’. Estas acciones son menos comunes; y podemos
   ignorarlas). Con mas frecuencia, el intérprete devuelve un valor.

   Al mismo tiempo que el intérprete devuelve un valor, también puede realizar
   cualquier otra cosa, como mover un cursor o copiar un fichero; este otro tipo
   de acción se denomina @:{efecto secundario}. Acciones que los humanos
   pensamos que son importantes, como imprimir resultados, con frecuencia son,
   “efectos secundarios” para el intérprete Lisp. La jerga puede sonar peculiar,
   pero resulta que es bastante fácil aprender a utilizar los efectos
   secundarios.

   En resumen, la evaluacion de una expresión simbólica normalmente causa que el
   intérprete devuelva un valor y tal vez lleve a cabo un efecto secundario; o
   al menos produca un error.

*** Evaluación de listas internas

    Si la evaluación se aplica a una lista que está dentro de otra lista, la
    lista externa puede usar el valor devuelto por la primer evaluación como
    información cuando se evalua la lista externa. Esto explica por qué las
    expresiones internas se evaluan primero: los valores devueltos son
    usados por las expresiones externas.

    Podemos investigar este proceso evaluando otro ejemplo de sumas. Coloca tu
    cursor después de la siguiente expresión y presiona @k{C-x C-e}:

    ..src > elisp
      (+ 2 (+ 3 3))
    < src..

    El número 8 aparecerá en el área de eco.

    Lo que ocurre es que el intérprete Lisp primero evalúa la expresión
    interna, @c{(+ 3 3)}, para lo cual se devuelve el valor 6; luego
    evalúa la expresión externa como si fuera escrita @c{(+ 2 6)}, que
    devuelve el valor 8. Puesto que no hay más expresiones adjuntas a
    evaluar el intérprete imprime este valor en el área de eco.

    Ahora es fácil comprender el nombre del comando invocado por el atajo @k{C-x
    C-e}: el nombre es @c{eval-last-sexp}. Las letras @c{sexp} son una
    abreviatura de ‘expresión simbólica’ @%i(symbolic expression), y @c{eval} es
    una abreviatura de ‘evaluar’ @%i(evaluate). El comando significa ‘evaluar
    la última expresión simbólica’.

    Como un experimento, puedes intentar evaluar la expresión poniendo el
    cursor al principio de la siguiente línea inmediatamente después de la
    expresión, o dentro de la expresión.

    Aquí hay otra copia de la expresión:

    ..src > elisp
      (+ 2 (+ 3 3))
    < src..

    Si colocas el cursor al principio de la línea en blanco que sigue
    inmediatamente a la expresión y presionas @k{C-x C-e}, aún obtendrás el
    valor 8 impreso en el área eco. Ahora coloca el cursor dentro de la
    expresión. Si lo pones justo después del penúltimo paréntesis (de modo que
    parezca estar sobre el último paréntesis), ¡obtendrás un 6 impreso en el área
    de eco! Esto se debe a que el comando evalúa la expresión @c{(+ 3 3)}.

    Ahora coloca el cursor inmediatamente después de un número. Presiona @k{C-x
    C-e} y obtendras el número en sí. En Lisp, si evalúas un número, obtienes el
    número en sí––así es cómo los números difieren de los símbolos. Si evalúas
    una lista que inicia con un símbolo como @c{+}, obtendras un valor devuelto
    que es el resultado del ordenador tras ejecutar las instrucciones que
    aparecen en la definición de la función ligada a ese nombre. Si se evalua un
    símbolo por sí mismo, sucede algo diferente, como veremos en la siguiente
    sección.

** Variables

   En Emacs Lisp, un símbolo puede estar ligado a un valor como a una definición
   de función. Los dos son diferentes. La definición de función es un conjunto
   de instrucciones que el ordenador ejecuta. Un valor, por otro lado, es algo,
   como un número o un nombre, que puede variar (razon por la cual tal símbolo
   se llama variable). El valor de un símbolo puede ser cualquier expresión de
   Lisp, por ejemplo un símbolo, un número, una lista, o una cadena. Un símbolo
   que tiene un valor con frecuencia se llama @:{variable}.

   Un símbolo puede ser tanto una definición de función como un valor asociado a el
   al mismo tiempo. O puede tener uno u otro. Los dos son independientes.
   Esto es algo similar a la forma en que el nombre Cambridge puede referirse a
   la ciudad en Massachusetts y tener alguna información ligada al nombre, por
   ejemplo, como “gran centro de programación”.

   Otra manera de pensar en esto es imaginar un símbolo como un mueble con
   cajones. La definición de función se coloca en un cajón, el valor en otro,
   etcetera. Lo que se pone en el cajón que contiene el valor
   se puede cambiar sin afectar el contenido del cajón que almacena la
   definición de función, y viceversa.

   La variable @c{fill-column} ilustra un símbolo con un valor adjunto: en
   cada buffer de GNU Emacs, este símbolo se establece en algún valor,
   normalmente 72 o 70, pero algunas veces en algún otro valor. Para encontrar
   el valor de este símbolo, evalúalo por sí mismo. Si estás leyendo esto
   dentro de GNU Emacs, puedes hacerlo poniendo el cursor después del
   símbolo y pulsando @k{C-x C-e}:

   ..src > elisp
     fill-column
   < src..

   Después de presionar @k{C-x C-e}, Emacs imprimió el número 72 en mi área de
   eco. Este es el valor que he establecido para @c{fill-column} mientras
   escribo esto. Puede ser diferente en tu búfer. Observa que el valor devuelto
   como una variable se imprime exactamente de la misma forma que el valor
   devuelto por una función tras ejecutar sus instrucciones. Desde el punto de
   vista del intérprete Lisp, un valor devuelto es un valor devuelto. La clase
   de expresion de la que proviene deja de importar una vez se conoce el
   valor.

   Un símbolo puede tener cualquier valor ligado a él o, siendo tecnicos, se
   puede @:{enlazar} la variable a un valor: a un número, por ejemplo 72; a una
   cadena, @c{"como esta"}; a una lista, como @c{(abeto pino roble)}; podemos
   incluso asociar una variable a una definición de función.

   Un símbolo puede vincularse a un valor de varias maneras. Consulta la Sección
   @l{#Establecer el valor de una variable}, para obtener información sobre
   como hacerlo.

*** Mensaje de error de un símbolo sin una función

    Cuando evaluamos @c{fill-column} para encontrar su valor como una
    variable, no pusimos paréntesis alrededor de la palabra. Esto se debe a
    que no pretendiamos usarla como nombre de función.

    Si @c{fill-column} fuese el primer o único elemento de una lista, el
    intérprete Lisp intentaría encontrar la definición de función adjunta.
    Pero @c{fill-column} no tiene una definición de función. Intenta evaluar
    esto:

    ..src > elisp
      (fill-column)
    < src..

    Se creará un buffer @f{*Backtrace*} que dice:

    ..example >
      ---------- Buffer: *Backtrace* ----------
      Debugger entered--Lisp error: (void-function fill-column)
        (fill-column)
        eval((fill-column))
        eval-last-sexp-1(nil)
        eval-last-sexp(nil)
        call-interactively(eval-last-sexp)
      ---------- Buffer: *Backtrace* ----------
    < example..

    (Recuerda, para salir del depurador y hacer que la ventana del depurador
    desaparezca, presiona @k{q} en el buffer @f{*Backtrace*}.)

*** Mensaje de error de un símbolo sin un valor

    Si intentas evaluar un símbolo que no tiene un valor asociado, recibirás un
    mensaje de error. Esto se puede ver experimentando con nuestra suma 2
    más 2. En la siguiente expresión, coloca el cursor justo después del
    @c{+}, antes del primer número 2, presiona @k{C-x C-e}:

    ..src > elisp
      (+ 2 2)
    < src..

    En GNU Emacs 22, se creará un buffer @f{*Backtrace*} que dice:

    ..example >
      ---------- Buffer: *Backtrace* ----------
      Debugger entered--Lisp error: (void-variable +)
        eval(+ nil)
        elisp--eval-last-sexp(nil)
        eval-last-sexp(nil)
        funcall-interactively(eval-last-sexp nil)
        call-interactively(eval-last-sexp nil nil)
        command-execute(eval-last-sexp)
      ---------- Buffer: *Backtrace* ----------
    < example..

    (De nuevo, puedes salir del depurador pulsando @k{q} en el búfer
    @f{*Backtrace*}.)

    Esta traza inversa es diferente del primer mensaje de error que vimos,
    que decia, @'c{Debugger entered--Lisp error: (void-function esto)}. En
    este caso, la función no tiene una valor como variable; mientras en
    el otro mensaje de error, la función (la palabra ‘esto’) no tenia una
    definición.

    En este experimento con el @c{+}, lo que hicimos fué hacer que el
    intérprete Lisp evalúe el @c{+} y busque el valor de la variable en lugar
    de la definición de la función. Hicimos esto colocando el cursor justo
    después del símbolo en lugar de ponerlo al final de los parentesis que
    cierran la lista como hicimos antes. Como consecuencia, el intérprete
    Lisp evaluó la expresión-s precedente, que en este caso era el @c{+} en sí.

    Ya que @c{+} no tiene un valor asociado, solo la definición de función,
    el mensaje de error informaba que el valor del símbolo como una variable
    esta vacío.

** Argumentos

   Para ver cómo se pasa la información a las funciones, veamos de nuevo
   nuestro viejo recurso, la suma de dos más dos. En Lisp, esto se escribe
   de la siguiente manera:

   ..src > elisp
     (+ 2 2)
   < src..

   Si evalúas esta expresión, el número 4 aparecerá en el área de eco. Lo que
   el intérprete de Lisp hace es sumar los números despues del @c{+}.

   Los números sumados por @c{+} se llaman @:{argumentos} de la función
   @c{+}. Estos números son la información que se da o se @:{pasa} a la función.

   La palabra ‘argumento’ proviene de la forma en que se usa en
   matemáticas y no se refiere a una disputa entre dos personas, En su lugar,
   se refiere a la información entregada a la función, en este caso, al
   @c{+}. En Lisp, los argumentos de una función son los átomos o listas que
   siguen a la función. Los valores devueltos por la evaluación de estos
   átomos o listas se transfieren a la función. Funciones diferentes requieren
   diferentes números de argumentos; algunas funciones no requieren ninguno
   en absoluto.@n{2}

*** Tipos de datos de los argumentos

    El tipo de datos que deben pasarse a una función dependen del tipo de
    información que utilice. Los argumentos de una función como @c{+} deben
    tener valores númericos, ya que @c{+} suma números. Otras funciones
    utilizan diferentes tipos de datos para sus argumentos.

    Por ejemplo, la función @c{concat} concatena o une dos o más cadenas de
    texto para producir una cadena. Los argumentos son cadenas. Concatenar
    las cadenas de caracteres @c{abc}, @c{def} produce una cadena @c{abcdef}.
    Esto se puede ver evaluando lo siguiente:

    ..src > elisp
      (concat "abc" "def")
    < src..

    El valor producido al evaluar esta expresión es @c{"abcdef"}.

    Una función como @c{substring} utiliza tanto una cadena como numeros como
    argumentos. La función devuelve una parte de la cadena, una subcadena del
    primer argumento. Esta función toma tres argumentos. Su primer argumento
    es la cadena de caracteres, el segundo y tercer argumento son números que
    indican el principio y el fin de la subcadena. Los números son un recuento
    del número de caracteres (incluyendo espacios y si signos de puntuacion) desde el
    principio de la cadena.

    Por ejemplo, si evalúas lo siguiente:

    ..src > elisp
      (substring "El rápido zorro marrón saltó." 10 15)
    < src..

    Veras aparecer @c{"zorro"} en el área de eco. Los argumentos son la cadena y
    los dos números.

    Ten en cuenta que la cadena pasada a @c{substring} es un unico átomo a
    pesar de estar compuesto de varias palabras separadas por espacios. Lisp
    considera todo entre las dos comillas como parte de la cadena, incluyendo
    los espacios. Puedes pensar en la función @c{substring} como una especie
    de ‘acelerador de particulas’ ya que toma un átomo de otro modo indivisible
    y extrae una parte. Sin embargo, @c{substring} solo es capaz de extraer una
    subcadena de un argumento que es una cadena, no de otro tipo de átomo por
    ejemplo un número o símbolo.

*** Un argumento como el valor de una variable o lista

    Un argumento puede ser un símbolo que devuelve un valor cuando se evalua.
    Por ejemplo, evaluar el símbolo @c{fill-column} en si mismo, devuelve un
    número. Este número se puede utilizar en una suma.

    Coloca el cursor después de la siguiente expresión y presiona @k{C-x C-e}:

    ..src > elisp
      (+ 2 fill-column)
    < src..

    El valor será dos mas el número que se obtiene evaluando @c{fill-column}.
    En mí caso, es 74, porque mi valor de @c{fill-column} es 72.

    Como acabamos de ver, un argumento puede ser un símbolo que devuelve un valor
    cuando se evalúa. Además, un argumento puede ser una lista que devuelve
    un valor cuando se evalúa. Por ejemplo, en la siguiente expresión, los
    argumentos de la función @c{concat} son las cadenas @c{"Los "} y
    @c{" zorros rojos."} y la lista @c{(number-to-string (+ 2 fill-column))}.

    ..src > elisp
      (concat "Los " (number-to-string (+ 2 fill-column)) " zorros rojos.")
    < src..

    Si evaluas esta expresión––y si, como con mi Emacs, @c{fill-column} se
    evalúa a 72––aparecerá @c{"Los 74 zorros rojos."} en el área de eco.
    (Ten en cuenta que debes poner espacios después de la palabra @'{Los} y
    antes de la palabra @'{zorros} para que aparezcan en la cadena final. La
    función @c{number-to-string} convierte el entero que devuelve la función
    suma a una cadena. @c{number-to-string} también se conoce como
    @c{int-to-string}.)

*** Número de argumentos variable

    Algunas funciones, como @c{concat}, @c{+}, o @c{*}, toman cualquier
    número de argumentos. (@c{*} es el símbolo para la multiplicacion.)
    Esto se puede ver evaluando cada una de las siguientes expresiones de la
    forma habitual.

    En el primer conjunto, las funciones no tienen argumentos:

    ..srci > elisp
      > (+)
      0
      > (*)
      1
    < srci..

    En este conjunto, las funciones tienen un argumento cada una:

    ..srci > elisp
      > (+ 3)
      3
      > (* 3)
      3
    < srci..

    En este conjunto, las funciones tienen tres argumentos cada una:

    ..srci > elisp
      > (+ 3 4 5)
      12
      > (* 3 4 5)
      60
    < srci..

*** Usando el tipo incorrecto de objeto como argumento

    Cuando a una función se le pasa un argumento del tipo incorrecto, el
    interpréte Lisp produce un mensaje de error. Por ejemplo, la función
    @c{+} espera que los valores de sus argumentos sean números. Como un
    experimento podemos pasar el símbolo citado @c{hola} en lugar de un
    número. Coloca el cursor después de la siguiente expresión y presiona
    @k{C-x C-e}:

    ..src > elisp
      (+ 2 'hola)
    < src..

    Al hacer esto se generará un mensaje de error. Lo qué ha ocurrido es que
    @c{+} ha intentado sumar el 2 al valor devuelto por @c{'hola}, pero el
    valor devuelto por @c{'hola} es el símbolo @c{hola}, no un número. Solo
    los números se pueden sumar. Por tanto @c{+} no pudo llevar a cabo su
    suma.

    Se creará e ingresara a un búfer @f{*Backtrace*} que dice:

    ..example >
      ---------- Buffer: *Backtrace* ----------
      Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p hola)
        +(2 hola)
        eval((+ 2 (quote hola)) nil)
        eval-last-sexp-1(nil)
        eval-last-sexp(nil)
        call-interactively(eval-last-sexp nil nil)
        command-execute(eval-last-sexp)
      ---------- Buffer: *Backtrace* ----------
    < example..

    Como de costumbre, el mensaje de error intenta ser útil y tiene sentido
    después de aprender a leerlo.@n{3}

    La primer parte del mensaje de error es sencilla; dice @'{wrong type
    argument} @%i(tipo de argumento incorrecto). A continuación viene la
    misteriosa jerga tecnica @'{number-or-marker-p}. Esta palabra está
    intentando decirte qué tipo de argumento espera @c{+}.

    El símbolo @c{number-or-marker-p} dice que el intérprete Lisp está
    intentando determinar si la información presentada (el valor del argumento)
    es un número o una marca (un objeto especial que representa una posición de
    buffer). Lo que hace es probar si se le estan dando numeros a sumar a
    @c{+}. También comprueba si el argumento es algo llamado marcador, que es una
    caracteristica específica de Emacs Lisp. (En Emacs, las ubicaciones en un
    búfer se registran como marcadores. Cuando se establece la marca con el
    comando @k{C-@@} o @k{C-SPC}, su posición se guarda como un marcador. La
    marca se puede consider un número––el número de caracteres es la ubicacion
    desde el principio del búfer.)  En Emacs Lisp, @c{+} se puede utilizar para
    sumar el valor numérico de los marcadores como números.

    La @'{p} en @c{number-or-marker-p} es la encarnación de una práctica
    iniciada en los primeros días de la programación Lisp. La @'{p} significa
    ‘predicado’. En la jerga usada por los primeros investigadores de Lisp,
    un predicado se refiere a una función para determinar si alguna propiedad
    es verdadera o falsa. Entonces la @'{p} nos dice que @c{number-or-marker-p}
    es el nombre de una función que determina si el argumento dado es un
    número o un marcador. Otros símbolos Lisp que finalizan en @'{p} incluyen
    @c{zerop}, una función que comprueba si su argumento tiene el valor de
    cero, y @c{listp}, una función que comprueba si su argumento es una
    lista.

    Finalmente, la última parte del mensaje de error es el símbolo @c{hola}.
    Este es el valor del argumento que se paso a @c{+}. Si a la suma se le hubiera
    pasado el tipo correcto de objeto, el valor habría sido un número, como
    37, en lugar de un símbolo como @c{hola}. Pero entonces no habrías
    recibido el mensaje de error.

*** La función @c{message}

    Al igual que @c{+}, la función @c{message} toma un número de argumentos
    variable. Se utiliza para enviar mensajes al usuario y es tan útil que
    la describiremos aqui.

    Se imprime un mensaje en el área de eco. Por ejemplo, puedes imprimir un
    mensaje en tu área de eco evaluando la siguiente lista:

    ..src > elisp
      (message "¡Este mensaje aparece en el área de eco!")
    < src..

    Toda la cadena entre comillas dobles es un unico argumento y se imprime
    @i{en su totalidad}. (Obseva que en este ejemplo, el mensaje mismo aparece
    en el área de eco entre comillas dobles; esto se debe a que ves el valor
    devuelto por la función @c{message}. En la mayoría de programas que
    escribiras, el texto se imprimira en el área de eco como un efecto
    secundario de @c{message}, sin las comillas. Consulta la Sección
    @l{#@c{multiplicar-por-siete} interactivo}, para ver en detalle un ejemplo
    de esto.)

    Sin embargo, si hay un @'c{%s} en la cadena de caracteres entre comillas, la
    función @c{message} no imprime el @'c{%s} como tal, si no que mira el siguente
    argumento a continuacion de la cadena. Evalúa el segundo argumento e
    imprime el valor en la ubicación de la cadena donde está el @'c{%s}.

    Puedes ver esto colocando el cursor después de la siguiente expresión y
    presionar @k{C-x C-e}:

    ..src > elisp
      (message "El nombre de este búfer es: %s." (buffer-name))
    < src..

    En Info, @c{"El nombre de este búfer es: *info*."} aparecerá en el área
    de eco. La función @c{buffer-name} devuelve el nombre del búfer como una
    cadena, que la función @c{message} inserta en lugar de @c{%s}.

    Para imprimir un valor como un entero, utiliza @'{%d} de la misma forma
    que @'{%s}. Por ejemplo, para imprimir un mensaje en el área de eco que
    indique el valor de @c{fill-column}, evalúa lo siguiente:

    ..src > elisp
      (message "El valor de fill-column es %d." fill-column)
    < src..

    En mi sistema, cuando evalúo esta lista, @c{"El valor de fill-column es
    72"} aparece en mi área de eco@n{4}.

    Si hay más de un @'{%s} en la cadena entre comillas, el valor del primer
    argumento después de la cadena se imprime en la posición del
    primer @'{%s} y el valor del segundo argumento se imprime en la posición
    del segundo @'{%s}, y así sucesivamente.

    Por ejemplo, si evalúas lo siguiente,

    ..src > elisp
      (message "¡Hay %d %s en la oficina!"
               (- fill-column 14) "elefantes rosas")
    < src..

    aparecerán un mensaje un poco caprichoso en el área de eco. En mi sistema
    dice @c{"¡Hay 58 elefantes rosas en la oficina!"}

    Se evalúa la expresión @c{(- fill-column 14)} y el número resultante
    se inserta en lugar del @'c{%d}; y la cadena entre comillas dobles,
    @c{"elefantes rosas"}, se trata como un unico argumento y se inserta
    en lugar del @'c{%s}. (Es decir, una cadena entre comillas dobles se
    evalúa así misma, como un número.)

    Por último, aquí está un ejemplo algo complejo que no solo ilustra el
    cálculo de un número, sino que también muestra como se puede usar una expresión
    dentro de una expresión para generar el texto que sustituira el @'c{%s}:

    ..src > elisp
      (message "Él vió %d %s"
               (- fill-column 36)
               (concat (substring
                        "Los rápidos zorros marrones saltaron." 12 18)
                       " rojos"
                       " saltando."))
    < src..

    En este ejemplo, @c{message} tiene tres argumentos: la cadena, @c{"Él vió
    %d %s"}, la expresión, @c{(- fill-column 32)}, y la expresion que comienza con
    la función @c{concat}. El valor resultante de la evaluación de @c{(-
    fill-column 32)} se inserta en lugar del @'{%d}; y el valor devuelto por
    la expresión que inicia con @c{concat} se inserta en lugar del @'{%s}.

    Cuando @c(fill-column) es 70 y evaluas la expresión, aparecera el
    mensaje @c{"Él vió 38 zorros rojos saltando."} en tu área de eco.

** Establecer el valor de una variable

   Hay varias formas de asignar un valor a una variable. Una de ellas es
   utilizar la función @c{set} o la función @c{setq}. Otra forma es utilizar
   @c{let} (Consulta la Seccion @l{#@c(let)}). (La jerga para este proceso es @:{ligar}
   @%i(bind) una variable a un valor.)

   Las siguientes secciones no solo describen cómo operan @c{set} y @c{setq},
   también ilustran como se pasan los argumentos.

*** Usando @c{set}

    Para establecer el valor del símbolo @c{flores} a la lista @c{'(rosa
    violeta margarita tulipan)}, evalúa la siguiente expresión colocando
    el cursor después de la expresión y presiona @k{C-x C-e}.

    ..src > elisp
      (set 'flores '(rosa violeta margarita tulipan))
    < src..

    La lista @c{(rosa violeta margarita tulipan)} aparecerá en el área de
    eco. Esto es la que @e{devuelve} la función @c{set}. Como efecto secundario,
    el símbolo @c{flores} esta ligado a la lista; es decir, el símbolo
    @c{flores}, puede verse como una variable, que entrega la lista como su
    valor. (Por cierto, este proceso, ilustra como un efecto secundario del
    intérprete Lisp, al establecer el valor, puede ser el principal efecto que
    nos interesa a los humanos. Esto se debe a que cada función Lisp debe
    devolver un valor si no obtiene un error, pero solo tendrá un efecto
    secundario si está diseñada para tenerlo.)

    Después de evaluar la expresión @c{set}, se puede evaluar el símbolo
    @c{flores} y devolvera el valor que se acaba de establecer. Aquí está
    el símbolo. Coloca el cursor al final de este y presiona @k{C-x C-e}.

    ..src > elisp
      flores
    < src..

    Al evalúar @c{flores}, aparece la lista @c{(rosa violeta margarita tulipan)}
    en el área de eco.

    Por cierto, si se evalúa @c{'flores}, la variable con una cita frente a
    ella, lo que verás en el área de eco es el símbolo en sí mismo, @c{flores}.
    Aquí está el símbolo citado, asi que puedes intentarlo:

    ..src > elisp
      'flores
    < src..

    Ten en cuenta también, que cuando se utiliza @c{set}, es necesario citar
    ambos argumentos, a menos que quieras que sean avaluados. Como no queremos
    que se evalue ninguno de los dos argumentos, se citan tanto la variable
    @c{flores}, como la lista @c{(rosa violeta margarita tulipan)}. (Cuando se
    utiliza @c{set} sin citar su primer argumento, el primer argumento se evalúa
    antes de realizar cualquier otra cosa. Si se hace esto y @c{flores} no tenía ya
    un valor, obtendras un mensaje de error de tipo, @'{El valor de símbolo como
    variable esta vacío}; por otro lado, si @c{flores} regresa un valor después
    de ser evaluada, @c{set} intentaría establecer el valor que fue devuelto.
    Hay situaciones donde esto es justo lo que la función a de hacer, pero estas
    situaciones son poco frecuentes.)

*** Usando @c{setq}

    Como una cuestión práctica, casi siempre se cita el primer argumento de
    @c{set}. La combinación de @c{set} y un primer argumento citado es tan
    común que tiene su propio nombre: la forma especial @c{setq}. Esta forma
    especial es similar a @c{set} excepto que el primer argumento se citado
    automáticamente, por lo que no es necesario escribir la marca de cita.
    Ademas, como una conveniencia adicional, @c{setq} permite asignar varias
    variables diferentes a diferentes valores, todo en una sola expresión.

    Para establecer el valor de la variable @c{carnívoros} a la lista
    @c{'(leon tigre leopardo)} usando @c{setq}, se utiliza la siguiente
    expresión:

    ..src > elisp
      (setq carnivoros '(leon tigre leopardo))
    < src..

    Esto es exactamente igual que usar @c{set} excepto que el primer
    argumento se cita automáticamente por @c{setq}. (La @'{q} en @c{setq}
    significa @c{quote} @%i(cita).)

    Con @c{set}, la expresión se vería asi:

    ..src > elisp
      (set 'carnivoros '(leon tigre leopardo))
    < src..

    Además, @c{setq} se puede utilizar para asignar diferentes valores a
    diferentes variables. El primer argumento se une al valor del segundo
    argumento, el tercer argumento se une a al valor del cuarto argumento, y
    así sucesivamente. Por ejemplo, podría utilizar lo siguiente para asignar
    una lista de árboles al símbolo @c{arboles} y una lista de herbívoros al
    símbolo @c{herbivoros}:

    ..src > elisp
      (setq arboles '(pino abeto roble arce)
            herbivoros '(gacela antilope cebra))
    < src..

    (La expresión podría también haber estado en una unica línea, pero podría
    no caber en una página; y a los humanos les resulta más fácil leer listas
    con un formato agradable.)

    Aunque he estado usando el término ‘asignar’, hay otra forma de pensar
    respecto a el funcionamiento de @c{set} y @c{setq}; y consiste en decir
    que @c{set} y @c{setq} hacen que el símbolo @e{apunte} a la lista. Esta
    ultima forma de pensar es muy común y en los proximos capítulos nos
    encontraremos con al menos un símbolo que tiene ‘puntero’ como parte de
    su nombre. El nombre se elige porque el símbolo tiene un valor,
    específicamente una lista, unida a el; o, expresado de otra manera, el
    símbolo se establece como “puntero” a la lista.

*** Conteo

    He aquí un ejemplo que muestra cómo utilizar @c{setq} en un contador. Es
    posible usar esto para contar cuantas veces se repite una parte de un
    programa. En primer lugar se necesita establecer una variable a cero; luego
    sumar uno al número cada vez que el programa se repita. Para hacer esto, se
    requiere una variable que sirva como contador, y dos expresiones: una
    expresión @c{setq} inicial que asigne la variable contador a cero; y una
    segunda expresión @c{setq} que incremente el contador cada vez se evalue.

    ..src > elisp
      (setq contador 0)                ; Llamemos a esto el inicializador.

      (setq contador (+ contador 1))   ; Este es el incremento.

      contador                         ; Este es el contador.
    < src..

    (El texto que sigue al @'{;} son los comentarios. Consulta la Seccion
    @l{#Cambiar una definición de función}.)

    Si evalúas la primera de estas expresiones, el inicializador, @c{(setq
    contador 0)}, y luego evalúas la tercera expresión, @c{contador}, el
    número @c{0} aparecerá en el área de eco. Si a continuación se evalúa la
    segunda expresión, el incremento, @c{(setq contador (+ contador 1))}, el
    contador tendrá el valor 1. Así que si evalúas de nuevo @c{contador}, el
    número @c{1} aparecerá en el área de eco. Cada vez que se evalúa la segunda
    expresión, el valor del contador se incrementara.

    Al evalúar el incremento, @c{(setq contador (+ contador 1))}, el intérprete
    Lisp evalúa en primer lugar la lista interna; esta es la suma. Para evaluar
    esta lista, se debe evaluar la variable @c{contador} y el número @c{1}.
    Cuando evalúa la variable @c{contador}, recibe su valor actual. Se pasa
    este valor y el número @c{1} a @c{+} que los suma. La suma se devuelve como
    el valor de la lista interior y pasa a @c{setq} que establece la variable
    @c{contador} a este nuevo valor. Por lo tanto, el valor de la variable
    @c{contador}, cambia.

** Resumen

   Aprender Lisp es como subir una colina en la que la primera parte es la
   mas empinada. Ahora has subido la parte más difícil; lo que queda se
   vuelve más fácil a medida que avanzas hacia adelante.

   En resumen,

   - Los programas Lisp se componen de expresiones, que son listas o átomos
     individuales.

   - Las listas se componen de cero o más átomos o listas internas, separadas
     por espacios en blanco y rodeadas por paréntesis. Una lista puede estar
     vacía.

   - Los átomos son símbolos de varios caracteres, como @c{forward-paragraph},
     símbolos de un solo caracter como @c{+}, cadenas de caracteres entre
     comillas dobles, o números.

   - Un número se evalúa a sí mismo.

   - Una cadena entre comillas dobles también se evalúa a sí misma.

   - Cuando se evalúa un símbolo en si, se devuelve su valor.

   - Cuando se evalúa una lista, el intérprete Lisp mira el primer símbolo en
     la lista y luego la definición de función asociada a ese símbolo. A
     continuación se ejecutan las instrucciones en la definición de la función.

   - Una marca de cita, @c{'}, le indica al intérprete Lisp que devuelva la
     siguiente expresión tal como esta escrita, y no evaluarla como lo haria si
     la cita no estuviera alli.

   - Los argumentos son la información que se pasa a una función. Los
     argumentos de una función se calculan evaluando el resto de los
     elementos de la lista de los cuales la función es el primer elemento.

   - Una función siempre devuelve un valor cuando se evalúa (a menos que
     se produzca un error); además, también se puede llevar a cabo alguna
     acción llamada “efecto secundario”. En muchos casos, el propósito
     principal de una función es crear un efecto secundario.

** Ejercicios

   Unos cuantos ejercicios simples:

   - Genera un mensaje de error evaluando un símbolo apropiado que no este
     entre paréntesis.

   - Genera un mensaje de error evaluando un símbolo apropiado que se encuentre
     entre paréntesis.

   - Crea un contador que se incrementa en dos en lugar de en uno.

   - Escribe una expresión que imprima un mensaje en el área de eco cuando se
     evalue.

* Practicando la Evaluación

  Antes de aprender a escribir una definición de función en Emacs Lisp, es
  útil dedicar un poco de tiempo a evaluar varias expresiones que ya han sido
  escritas. Estas expresiones serán listas con funciones como su primer (y con
  frecuencia único) elemento. Dado que algunas de las funciones asociadas con
  búfers son a la vez simples e interesantes, empezaremos por ellas. En esta
  sección, vamos a evaluar algunas. En otra sección, estudiaremos el código de
  varias otras funciones relacionadas con búfers, para ver la forma cómo fueron
  escritas.

  @i{Siempre que se le da un comando de edición} a Emacs Lisp, como el
  comando para mover el cursor o para desplazarse por la pantalla, @i{se está
  evaluando una expresión}, cuyo primer elemento es una función. @i{Así es cómo
  funciona Emacs}.

  Al presionar las teclas, haces que el interprete Lisp evalue una expresion y
  asi es como obtienes resultados. Incluso escribir texto plano implica
  evalúar una función de Emacs Lisp, en este caso, se utiliza
  @c{self-insert-command}, que simplemente inserta el caracter que has escrito.
  Las funciones que se evalúan presionando atajos de teclado se llaman funciones
  @:{interactivas}, o @:{comandos}; la forma de hacer que una funcion sea
  interactiva se ilustrara en el capítulo sobre cómo escribir definiciones de
  funcion. Consulta la Seccion @l{#Crear una Función Interactiva}.

  Además de presionar comandos de teclado, hemos visto una segunda manera de
  evaluar una expresión: colocar el cursor después de una lista y presionar
  @k{C-x C-e}. Esto es lo que haremos en el resto de esta sección. Hay otras
  maneras de evaluar una expresión; estas serán descritas a medida que llegemos a
  ellas.

  Ademas de utilizarlas para prácticar la evaluación, las funciones que se
  muestran en las siguientes secciones son importantes por derecho propio. Un
  estudio de estas funciones deja claro la distinción entre búfers y ficheros,
  cómo cambiar a un búfer, y como determinar una ubicación dentro de el.

** Nombres de búfer

   Las dos funciones, @c{buffer-name} y @c{buffer-file-name}, muestran la
   diferencia entre un fichero y un búfer. Cuando se evalúa la siguiente
   expresión, @c{(buffer-name)}, el nombre del buffer aparece en el area eco.
   Al evaluar @c{(buffer-file-name)}, el nombre del fichero al que hace
   referencia el búfer aparece en el área de eco. Por lo general, el nombre
   devuelto por @c{(buffer-name)} es el mismo que el nombre del fichero al
   que hace referencia, y el nombre devuelto por @c{(buffer-file-name)} es la
   ruta completa del fichero.

   Un fichero y un búfer son dos entidades diferentes. Un fichero es la
   información grabada de manera permanente en el ordenador (a menos que se
   elimine). Un búfer, por otro lado, es información dentro de Emacs que
   desaparecerá al final de la sesión de edición (o cuando mates el búfer).
   Por lo general, un búfer contiene información que se ha copiado
   desde un fichero; decimos que el búfer está @:{visitando} ese fichero.
   Esta copia es en la que se trabaja y modifica. Los cambios en el búfer no
   modifican el fichero, hasta guardar el búfer. Al guardar el búfer, el búfer
   se copia en el fichero y por lo tanto se guarda de forma permanente.

   Si está leyendo esto dentro de GNU Emacs, puedes evaluar cada una de las
   siguientes expresiones colocando el cursor después de estas y pulsando @k{C-x
   C-e}.

   ..src > elisp
     (buffer-name)

     (buffer-file-name)
   < src..

   Cuando hago esto en el búfer @f(*info*), el valor devuelto evaluando
   @c{(buffer-name)} es @f{"*info*"}, y el valor devuelto evaluando
   @c{(buffer-file-name)} es @f{nil}.

   Por otro lado, mientras escribo este documento, el valor devuelto por la
   evaluación de @c{(buffer-name)} es @c{"introduction.texinfo"}, y el valor
   evaluando @c{(buffer-file-name)} es @c{"/gnu/work/intro/introduction.texinfo"}.

   El primero es el nombre del búfer y el segundo es el nombre del
   fichero. En Info, el nombre del búfer es @f{"*info*"}. Info no apunta a
   ningún fichero, por lo que el resultado de evaluar @c{(buffer-file-name)}]
   es @f{nil}. El símbolo @c{nil} proviene del latin, significa ‘nada’; en
   este caso, significa que el búfer no está asociado con ningun fichero.
   (En Lisp, @c{nil} también se utiliza con el significado de ‘falso’ y es
   sinómino para la lista vacía, @c{()}.)

   Al escribir esto, el nombre de mi búfer es @c{"introduction.texinfo"}. El
   nombre del fichero al que apunta es @c{"/gnu/work/intro/introduction.texinfo"}.

   (En las expresiones, los paréntesis le indican al intérprete Lisp que trate a
   @c{buffer-name} y @c{buffer-file-name} como funciones; sin los paréntesis, el
   intérprete intentaría evaluar los símbolos como variables. Consulta la Sección
   @l{#Variables}.)

   A pesar de la distinción entre ficheros y búfers, con frecuencia encontraras
   personas referirse a un fichero cuando se refieren a un búfer y viceversa. De
   hecho, la mayoría de la gente dice, “Estoy editando un fichero”, en lugar de
   decir, “Estoy editando un búfer que pronto voy a guardar en un fichero”. Esto
   casi siempre queda claro a partir del contexto de lo que la gente quiere
   decir. No obstante, al tratar con programas de ordenador, es importante
   tener en cuenta la distinción, ya que el ordenador no es tan inteligente
   como una persona.

   Por cierto, la palabra ‘búfer’, viene del significado de la palabra como un
   cojín que amortigua la fuerza de una colisión. En los primeros ordenadores,
   un búfer amortiguaba la interacción entre los ficheros y la unidad central de
   procesamiento del ordenador. Los tambores o cintas que contenian un fichero y
   la unidad de procesamiento eran equipos muy diferentes entre si, que
   trabajaban a su propia velocidad, por rafagas. El búfer hizo posible que
   ambos trabajaran juntos de manera efectiva. Con el tiempo, el búfer pasó de
   ser un intermediario, un lugar de almacenamiento temporal, a ser el lugar
   donde se realiza el trabajo. Esta transformación se parace bastante a la de
   un pequeño puerto que se convierte en una gran ciudad: una vez fué
   simplemente el lugar donde la carga se almacenaba temporalmente antes de ser
   cargada en los barcos; despues se convirtio en un centro comercial y cultural
   por derecho propio.

   No todos los búfers están asociados con ficheros. Por ejemplo, el búfer
   @f(*scratch*) no visita ningun fichero. Del mismo modo, un búfer
   @f{*Help*} no está asociado a ningun fichero.

   En los viejos tiempos, cuando se carecia de un fichero @f{~/.emacs} y se
   iniciaba una sesión Emacs escribiendo unicamente el comando @c{emacs}, sin
   nombrar ningun fichero, Emacs iniciaba con el búfer @f{*scratch*}
   visible. Hoy en día, veras una pantalla de bienvenida. Puedes seguir uno de
   los comandos sugeridos en dicha pantalla, visitar un fichero, o presionar
   la barra de espacio para acceder al búfer @f{*scratch*}.

   Si cambias al búfer @f{*scratch*}, escribe @c{(buffer-name)}, coloca el
   cursor al final de la expresión, y presiona @k{C-x C-e} para evaluar la
   expresión. El nombre @c{*scratch*} será devuelto y aparecerá en el área
   de eco. @c{*scratch*} es el nombre del búfer. Al escribir y evaluar
   @c{(buffer-file-name)} en el búfer @f{*scratch*}, aparecerá @c{nil} en el
   área de eco, igual que cuando evalúas @c{(buffer-file-name)} en Info.

   Por cierto, si estas en el búfer @f{*scratch*} y quieres que el
   valor devuelto por una expresión aparezca en el búfer en sí y no en el
   área de eco, presiona @k{C-u C-x C-e} en lugar de @k{C-x C-e}. Esto hace
   que el valor devuelto aparezca después de la expresión. El búfer se verá
   así:

   ..example >
     (buffer-name)"*scratch*"
   < example..

   No se puede hacer esto en Info ya que Info es de solo lectura y no se
   permitirá cambiar el contenido del búfer. Pero puedes hacer esto en
   cualquier búfer que puedas editar; y cuando escribes código o
   documentación (como este libro), esta caracteristica es muy útil.

** Obtención de Búfers

   La función @c{buffer-name} devuelve el @e{nombre} del búfer; para obtener
   el búfer @e{en sí}, se necesita una función diferente: la función
   @c{current-buffer}. Si utilizas esta función en el código, lo que se
   obtiene es el búfer en sí.

   Un nombre y el objeto o entidad al que se refiere el nombre son
   diferentes entre si. Tu no eres tu nombre, eres una persona a la que se
   refieren los demas por tu nombre. Si pides hablar con Jorge y alguien te
   entrega una tarjeta con las letras @'{J}, @'{o}, @'{r}, @'{g}, y @'{e}
   escritas, podrias divertirte, pero no estarías satisfecho. No quieres
   hablar con el nombre, sino con la persona a la que se refiere el
   nombre. Un búfer es similar: el nombre del búfer scratch es
   @f{*scratch*}, pero el nombre no es el búfer. Para obtener un búfer en
   sí, es necesario utilizar una función como @c{current-buffer}.

   Sin embargo, hay una ligera complicación: si evalúas @c{current-buffer} en
   una expresión por sí sola, como haremos aquí, lo que se ve es una
   representación impresa del nombre del búfer sin el contenido del búfer. Emacs
   funciona de esta forma por dos razones: el búfer puede contener miles de
   líneas––demasiado largo para mostrarse convenientemente; y, otro búfer
   puede tener el mismo contenido pero un nombre diferente, y es importante
   distinguir entre ellos.

   Aquí hay una expresión que contiene la función:

   ..src > elisp
     (current-buffer)
   < src..

   Si evalúas esta expresión en Info de la manera habitual, aparecerá
   @f{#<buffer *info*>} en el área de eco. El formato especial indica que se
   está devuendo el búfer en sí, en lugar de solo su nombre.

   Por cierto, si bien puedes escribir un número o símbolo en un programa, no
   se puede hacer esto con la representación impresa del búfer: la única
   manera de optener un búfer en sí mismo es con una función como
   @c{current-buffer}.

   Una función relacionada es @c{other-buffer}. Esta devuelve el último bufer
   seleccionado distinto al que te encuentras actualmente, no una
   representación impresa de su nombre. Si recientemente has ido y vuelto del
   búfer @f{*scratch*}, @c{other-buffer} devolverá ese búfer.

   Puedes ver esto evaluando la expresión:

   ..src > elisp
     (other-buffer)
   < src..

   Verás que @c{#<buffer *scratch*>} aparece en el área de eco, o el nombre de
   cualquier otro búfer al que allas cambiado anteriormente reciente@n{5}

** Cambiando búfers

   La función @c{other-buffer} realmente proporciona un búfer cuando se
   utiliza como argumento de una función que requiera uno. Podemos ver esto
   usando @c{other-buffer} y @c{switch-to-buffer} para cambiar a un búfer
   diferente.

   Pero primero, una breve introducción a la función @c{switch-to-buffer}.
   Cuando cambiaste de ida y vuelta de Info al búfer @f{*scratch*} para evaluar
   @c{(buffer-name)}, probablemente pulsaste @k{C-x b} y luego escribiste
   @f{*scratch*}@n{6} en el minibuffer cuando se solicito el nombre del
   buffer al que querias cambiar. El atajo, @k{C-x b}, hace que el intérprete
   Lisp evalúe la función interactiva @c{switch-to-buffer}. Como hemos dicho
   anteriormente, así es como funciona Emacs: diferentes atajos de teclado
   llaman o ejecutan diferentes funciones. Por ejemplo, @k{C-f} llama a
   @c{forward-char}, @k{M-e} llama a @c{forward-sentence}, etcétera.

   Al escribir @c{switch-to-buffer} en una expresión, y darle un búfer al
   que cambiar, podemos cambiar de búfer tal y como lo hace @k{C-x b}.

   ..src > elisp
     (switch-to-buffer (other-buffer))
   < src..

   El símbolo @c{switch-to-buffer} es el primer elemento de la lista, por lo
   que el intérprete Lisp lo tratará como una función y llevara a cabo las
   instrucciones adjuntas al mismo. Pero antes de hacer esto, el intérprete
   observara que @c{other-buffer} está dentro de paréntesis y trabajara en
   este símbolo primero. @c{other-buffer} es el primer (y en este caso, el
   único) elemento de esta lista, por lo que el intérprete llama o ejecuta la
   función. Esto devuelve un búfer distinto al actual. A continuación, el
   intérprete ejecuta @c{switch-to-buffer}, pasando, como argumento, el
   búfer devuelto, que es al que Emacs cambiara. Si estás leyendo esto en
   Emacs, prueba ahora. Evalúa la expresión. (Para regresar, presiona @k{C-x b
   RET}.)@n{7}

   En los ejemplos de las secciones siguentes, veras con más frecuencia la
   función @c{set-buffer} que @c{switch-to-buffer}. Esto se debe a la
   diferencia entre los programas de ordenador y los seres humanos: los humanos
   tienen ojos y esperan ver el búfer en el que están trabajando en la
   terminal de su ordenador. Esto es tan evidente, que casi no hace falta decirlo. Sin
   embargo, los programas no tienen ojos. Cuando un programa de ordenador
   trabaja en un búfer, el búfer no necesita ser visible en la pantalla.

   @c{switch-to-buffer} está diseñado para humanos y hace dos cosas
   diferentes: cambia el búfer a el que Emacs dirige la atención; y cambia
   el búfer mostrado en la ventana al nuevo búfer. @c{set-buffer}, por otro
   lado, solo hace una cosa: cambia la atención del programa de ordenador a
   un búfer diferente. El búfer en la pantalla permanece sin cambios (por
   supuesto, normalmente no pasa nada hasta que el comando termina de
   ejecutarse).

   Además, acabamos introduciendo otro termino tecnico, la palabra
   @:{llamada}. Cuando se evalúa una lista en la que el primer símbolo es una
   función, se llama a esa función. El uso del término viene de la
   noción de la función como una entidad que puede algo hacer por ti si la
   ‘llamas’––al igual que un fontanero es una entidad que puede arreglar
   una fuga si lo llamas.

** Tamaño del búfer y ubicación del punto

   Finalmente, veamos algunas funciones bastante simples, como @c{buffer-size},
   @c{point}, @c{point-min}, y @c{point-max}. Estas proporcionan información
   sobre el tamaño de un búfer y la ubicación del punto dentro de el.

   La función @c{buffer-size} te dice el tamaño del búfer actual; es decir,
   la función devuelve un conteo del número de caracteres en el buffer.

   ..src > elisp
     (buffer-size)
   < src..

   Puedes evaluar esto de la forma habitual, coloca el cursor después de la
   expresión y presiona @k{C-x C-e}.

   En Emacs, la posición actual del cursor se llama @:{punto}. La
   expresión @c{(point)} devuelve un número que indica donde esta situado el
   cursor como un conteo del número de caracteres desde el principio del
   búfer hasta el punto.

   Puedes ver el conteo de caracteres del punto para este búfer evaluando la
   siguiente expresión de la forma habitual:

   ..src > elisp
     (point)
   < src..

   Mientras escribo esto, el valor de @c{point} es 65724. La función
   @c{point} se utiliza con frecuencia en algunos de los ejemplos mas
   adelante en este libro.

   El valor del punto depende, por supuesto, de su ubicacion dentro del
   búfer. Si evaluas el punto en este lugar, el número será mayor:

   ..src > elisp
     (point)
   < src..

   Para mí, el valor del punto en esta posición es 66043, lo que significa que
   hay 319 caracteres (incluyendo espacios) entre las dos expresiones.  (Sin
   duda, verás números diferentes, ya que lo habré editado desde que evalue el
   punto por primera vez.)

   La función @c{point-min} es similar a @c{point}, pero devuelve el valor
   mínimo permitido del punto en el búfer actual. Este es el numero 1 a menos
   que @:{narrowing} esté en efecto. (Narrowing @%i{Reduccion} es un mecanismo
   mediante el cual puedes restringirte a ti mismo, o a un programa, a operar solo
   en un parte de un búfer. Consulta la Sección @l{#Reducir y Extender}.)  Del mismo
   modo, la función @c{point-max} devuelve el valor máximo permitido del punto
   en el búfer actual.

** Ejercicio

   Busca un fichero en el que trabarjar y avanza hasta su mitad. Encuentra el
   nombre de búfer, el nombre del fichero, su tamaño, y la posición en el
   fichero.

* Cómo escribir definiciones de funcion

  Cuando el intérprete Lisp evalúa una lista, mira si el primer símbolo tiene
  una definición de funcion adjunta; o, dicho de otro modo, si el símbolo apunta
  a una definición de función. Si lo hace, el ordenador ejecuta las
  instrucciones de la definición. Un símbolo que tiene una
  definición de función se llamada, simplemente, una función (aunque hablando
  con propiedad, la definición es la función y el símbolo hace referencia a ella.)

  Todas las funciones se defininen en términos de otras funciones, a
  excepción de algunas funciones @:{primitivas} que estan escritas en el lenguaje de
  programación C. Cuando escribas definiciones de funcion, debes
  escribirlas en Emacs Lisp y utilizar otras funciones como bloques de
  construcción. Algunas de las funciones que utilizaras estaran a su vez escritas
  en Emacs Lisp (quizás por tí) y otras serán primitivas escritas en C. Las
  funciones primitivas se usan exactamente igual que las escritas en Emacs
  Lisp y se comportan de igual forma. Están escritas en C para que podamos
  ejecutar facilmente GNU Emacs en cualquier ordenador que tenga la potencia
  suficiente y pueda ejecutar C.

  Permíteme volver a enfatizar esto: cuando se escribe código en Emacs Lisp, no
  se distinge entre el uso de funciones escritas en C y el uso de funciones
  escritas en Emacs Lisp. La diferencia es irrevelante. Menciono la distinción
  solo porque es interesante conocerla. De hecho, a menos de que investigues, no
  sabras si una función ya escrita esta en Emacs Lisp o en C.

** La forma especial @c{defun}

   En Lisp, un símbolo como @c{mark-whole-buffer} tiene un código adjunto que le
   dice al ordenador que hacer cuando se invoca la función. Este código se
   denomina la @:{definición de función} y se crea evaluando una expresión Lisp
   que comienza con el símbolo @c{defun} (que es una abreviatura para @e{define
   function} @%i(definir función)). Debido a que @c{defun} no evalúa sus
   argumentos de la manera habitual, se le llama una @:{forma especial}.

   En las siguientes secciones, veremos algunas definiciones de función presentes
   dentro del código fuente de Emacs, como @c{mark-whole-buffer}.
   En esta sección, describiremos una definición de función sencilla para que
   puedas ver su aspecto. Esta definición de función usa aritmética porque es
   un ejemplo simple. A algunas personas les disgustan los ejemplos que usan
   aritmética; sin embargo, si eres una persona asi, no te desesperes. Casi
   ningun codigo a estudiar en el resto de esta introducción implica
   aritmética o matemáticas. Los ejemplos involucran principalmente texto de
   una forma u otra.

   Una definición de función tiene hasta cinco partes despues de la
   palabra @c{defun}:

   1. El nombre del símbolo al se debe vincular la definición de función.

   2. Una lista de los argumentos que se pasan a la función. Si no hay
      argumentos que pasar a la función, tendremos una lista vacía, @c{()}.

   3. Documentación que describe la función. (Técnicamente opcional, pero
      muy recomendable.)

   4. Opcionalmente, una expresión para hacer que la función sea interactiva, de
      manera que se puede utilizarla presionando @k{M-x} seguido del nombre de la
      función; o pulsando una tecla o atajo de teclado.

   5. El código que indica a el ordenador qué hacer: el @:{cuerpo} de la
      definición de función.

   Es útil pensar que las cinco partes de una definición de función estan
   organizadas como en una plantilla, con ranuras para cada parte:

   ..src > elisp
     (defun nombre-de-función (argumentos…)
       "documentación-opcional…"
       (interactive informacion-de-paso-de-argumentos)     ; opcional
       cuerpo…)
   < src..

   A modo de ejemplo, aquí está el código de una función que multiplica su
   argumento por 7. (Este ejemplo no es interactivo. Consulta la Sección @l{#Crear una
   Función Interactiva}, para obtener esa información.)

   ..src > elisp
     (defun multiplicar-por-siete (numero)
       "Multiplica NUMERO por siete."
       (* 7 numero))
   < src..

   Esta definición comienza con un paréntesis y el símbolo @c{defun} seguido
   por el nombre de la función.

   El nombre de la función es seguido por una lista que contiene los
   argumentos que seran pasados a la función. Esta lista se llama @:{lista de
   argumentos}. En este ejemplo, la lista solo tiene un elemento, el símbolo
   @c{numero}. Cuando se utiliza la función, el símbolo sera asociado al
   valor que se utiliza como argumento de la función.

   En lugar de elegir la palabra @c{numero} para el nombre del argumento,
   podría haber escogido cualquier otro nombre. Por ejemplo, la palabra
   @c{multiplicando}. Escogi la palabra ‘numero’ porque indica qué tipo de
   valor se pretende para este espacio; pero podría haber elegido
   ‘multiplicando’ para indicar el papel que jugara el valor en el
   funcionamiento de la función. Podría haberlo llamado @c{foogle}, pero
   habría sido una mala elección, ya que no comunicaria a los humanos qué
   significa. La elección del nombre es responsabilidad del programador y
   debe elegirse para hacer que el significado de la función quede claro.

   De hecho, puedes elegir cualquier nombre que desees para un símbolo en una
   lista de argumentos, incluso el nombre de un símbolo utilizado en alguna otra
   función: el nombre que utilices en una lista de argumentos es privado
   para esa definición particular. En esta definición, el nombre hace
   referenecia a una entidad diferente a cualquiera que utilice el mismo
   nombre fuera de la definición de función. Supón que tu familia te apodan
   ‘Enano’; cuando tus familiares digan ‘Enano’, queren hacer referencia a
   ti. Pero fuera de tu familia, en una película, por ejemplo, el nombre
   ‘Enano’ se refiere a alguien más. Debido a que el nombre en una lista de
   argumentos es privado de la definición de la función, se puede cambiar
   el valor de un símbolo dentro del cuerpo de una función sin cambiar su
   valor fuera de la función. El efecto es similar al producido por la
   expresión @c{let}. (Consulta la sección @l{#@c(let)}.)

   La lista de argumentos es seguida por la cadena de documentación que
   describe la función. Esto es lo ves cuando presionas @k{C-h f} y escribes
   el nombre de una función. Por cierto, cuando escribas una cadena de
   documentación como esta, debes confeccionar la primera linea como una
   frace completa ya que algunos comandos, como @c{apropos}, solo imprimen
   la primer línea de una cadena de documentación de varias líneas.
   Ademas, no debes indentar la segunda línea de la cadena de documentación,
   si tienes una, porque se ve extraño al utilizar @k{C-h f}
   @%c(describe-function). La cadena de documentación es opcional, pero es
   tan útil, que debería incluirse en casi cualquier función que escribas.

   La tercer línea del ejemplo consiste en el cuerpo de la definición de
   función. (La mayoría de las definiciones de funcion, claro esta, son más
   extensas que esto.) En esta función, el cuerpo es la lista, @c{(* 7
   numero)}, que indica multiplicar el valor de @c{numero} por 7. (En Emacs
   Lisp, @c{*} es la función para multiplicar, al igual que @c{+} es la
   función para sumar.

   Cuando se utiliza la función @c{multiplicar-por-siete}, el argumento
   @c{numero} se evalúa al número que desees usar. He aquí un ejemplo que
   muestra como utilizar @c{multiplicar-por-siete}; ¡pero no trates de evaluar
   esto primero!.

   ..src > elisp
     (multiplicar-por-siete 3)
   < src..

   El símbolo @c{numero}, especificado en la definición de función en la
   siguiente sección, se da o “une a” el valor 3 en el uso real de la
   función. Observa que aunque @c{numero} estaba dentro de paréntesis en la
   definición de función, el argumento pasado a la función
   @c{multiplicar-por-siete} no está entre paréntesis. Los paréntesis se
   escriben en la definición de función para que el ordenador pueda averiguar
   donde termina la lista de argumentos y donde inicia el resto de la definición de
   función.

   Si evalúas este ejemplo, es probable que obtengas un mensaje de error.
   (¡adelante, intentalo!) Esto se debe a que hemos escrito la definición de
   función, pero aún no se ha comunicado al ordenador sobre la definición––aun no
   hemos instalado (o ‘cargado’) la definición de función en Emacs. Instalar
   una función es el proceso de comunicar al intérprete Lisp la definición de
   la función. La instalación se describe en la siguiente sección.

** Instalar una definición de función

   Si estás leyendo esto dentro en Emacs, puedes probar la función
   @c{multiplicar-por-siete} evaluando en primer lugar la definición de función y
   luego evaluando @c{(multiplicar-por-siete 3)}. Hay una copia de la
   definición a continuación. Coloca el cursor después del último paréntesis
   de la definición de función y presiona @k{C-x C-e}. Al hacer esto,
   @c{multiplicar-por-siete} aparecerá en el área de eco. (Esto significa
   que cuando se evalua una definición de función, el valor devuelto es
   el nombre de la función definida.) Al mismo tiempo, esta acción instala la
   definición de función.

   ..src > elisp
     (defun multiplicar-por-siete (numero)
       "Multiplica NUMERO por siete."
       (* 7 numero))
   < src..

   Al evaluar este @c{defun}, estas instanlado @c{multiplicar-por-siete} en
   Emacs. La función ahora es una parte de Emacs tanto como
   @c{forward-word} o cualquier otra función de edición que utilices.
   (@c{multiplicar-por-siete} permanecera instalado hasta que salgas de
   Emacs. Para volver a cargar el código automáticamente cada vez que inicie
   Emacs, revisa la sección @l{#Instalar Código Permanentemente}.)

   Puedes ver el efecto de instalar @c{multiplicar-por-siete} evaluando el
   siguiente ejemplo. Coloca el cursor después de la siguiente expresión y
   presiona @k{C-x C-e}. El número 21 aparacerá en el área de eco.

   ..src > elisp
     (multiplicar-por-siete 3)
   < src..

   Si lo deseas, puedes leer la documentación de la función presiona @k{C-h
   f} @%c(describe-function) y luego escribe el nombre de la función,
   @c{multiplicar-por-siete}. Al hacer esto, aparecerá una ventana @f{*Help*}
   en tu pantalla diciendo:

   ..example >
     multiplicar-por-siete is a Lisp function.
     (multiplicar-por-siete NUMERO)

     Multiplica NUMERO por siete.
   < example..

   (Para volver a una sola ventana en tu pantalla, presiona @k{C-x 1}.)

*** Cambiar una definición de función

    Si quieres modificar el código de @c{multiplicar-por-siete}, simplemente
    reescribelo. Para instalar la nueva versión en lugar de la anterior, evalúa
    nuevamente la definición de la función. Esta, es la forma de modificar el
    código en Emacs. Es muy sencillo,

    A modo de ejemplo, puedes cambiar la función @c{multiplicar-por-siete}
    para sumar el número a sí mismo siete veces en lugar de multiplicar el
    número por siete. Esto produce el mismo resultado, pero por una ruta
    diferente. Al mismo tiempo, añadiremos un comentario al codigo; un
    comentario es texto que el intérprete Lisp ignora, pero un lector humano
    puede encontrar útil o esclarecedor. El comentario es, que esta es la
    “segunda versión”.

    ..src > elisp
      (defun multiplicar-por-siete (numero)       ; Segunda versión.
        "Multiplica NUMERO por siete."
        (+ numero numero numero numero numero numero numero))
    < src..

    El comentario sigue a un punto y coma, @'{;}. En Lisp cualquier cosa en
    una línea despues de un punto y coma es un comentario. El fin de la línea
    es el fin del comentario. Para extender un comentario por dos o más
    líneas, inicia cada línea con un punto y coma.

    Consulta las Secciónes @l(#Empieza por un fichero @f{.emacs}) y
    @l{elisp.html#Comments<>Comentarios} en @e(El Manual de Referencia de GNU
    Emacs Lisp), para más informacion sobre los comentarios.

    Puedes instalar esta versión de @c{multiplicar-por-siete} evaluándo esta
    del mismo modo en que evaluaste la primer función: coloca el cursor
    después del último paréntesis y presiona @k{C-x C-e}.

    En resumen, asi es como puedes escribir código en Emacs Lisp: escribes una
    función; la instalas; la pruebas; luego haces correcciones o mejoras y la
    vuelves a instalar.

** Crear una función interactiva

   Puedes hacer a una función interactiva colocando una lista que inicia con la
   forma especial @c{interactive} inmediatamente después de la documentación.
   Un usuario puede invocar una función interactiva con @k{M-x} seguido del
   nombre de la función; o con un atajo de teclado ligado a esta, por
   ejemplo, presionando @k{C-n} para @c{next-line} o @k{C-x h} para
   @c{mark-whole-buffer}.

   Cusionamente, cuando se llama a una función interactiva interactivamente, el
   valor devuelto no se muestra automáticamente en el área de eco. Esto se debe
   a que a menudo se llama a una función interactiva por sus efectos
   secundarios, como avanzar hacia adelante una palabra o una línea,
   y no por el valor devuelto. Si el valor devuelto se mostrara en el área
   de eco cada vez que presionas una tecla, seria muy molesto.

   Tanto el uso de la forma especial @c{interactive} y la forma de mostrar
   un valor en el área de eco se pueden ilustrar creando una versión
   interactiva de @c{multiplicar-por-siete}.

   Aquí está el código:

   ..src > elisp
     (defun multiplicar-por-siete (numero)       ; Versión Interactiva.
       "Multiplica NUMERO por siete."
       (interactive "p")
       (message "El resultado es %d" (* 7 numero)))
   < src..

   Para instalar este código, coloca el cursor después del ultimo parentesis y
   presiona @k{C-x C-e}. El nombre de la función aparecerá en el área de eco.  A
   continuacion, puedes utilizar este código al presionar @k{C-u} segudo de un
   número, luego @k{M-x multiplicar-por-siete} y finalmente @k{RET}. En el área
   de eco aparecerá la frase @'{El resultado es …} seguida por el producto.

   Hablando en terminos mas generales, puedes invocar una función como ésta
   de dos maneras:

   1. Escribiendo un argumento prefijo que contenga el número a pasar, y luego
      presionar @k{M-x} y el nombre de la función, como ocurre con
      @k{C-u 3 M-x forward-sentence}; o,

   2. Pulsando cualquier tecla o atajo de teclado ligado a la función, como
      ocurre con @k{C-u 3 M-e}.

   Ambos ejemplos operan de forma identica moviendo el punto hacia adelante
   tres oraciones. (Ya que @c{multiply-by-seven} no esta ligado a un atajo, no
   se puede utilizar como ejemplo.)

   (Consulta la Seccion @l{#Algunos Atajos de teclado}, para aprender como vincular un
   comando a una atajo.)

   Un argumento prefijo se pasa a una función interactiva pulsando la tecla
   @k{META} seguida de un número, por ejemplo, @k{M-3 M-e}, o con @k{C-u} y
   luego un número, por ejemplo, @k{C-u 3 M-e} (si presionas @k{C-u} sin
   ningun número, el valor por defecto es 4).

*** @c{multiplicar-por-siete} interactivo

    Veamos es uso de la forma especial @c{interactive} y luego la función
    @c{message} en la versión interactiva de @c{multiplicar-por-siete}.
    Recordaras que la definición de función tiene el siguiente aspecto:

    ..src > elisp
      (defun multiplicar-por-siete (numero)       ; Versión Interactiva.
        "Multiplica NUMERO por siete."
        (interactive "p")
        (message "El resultado es %d" (* 7 numero)))
    < src..

    En esta función, la expresión, @c{(interactive "p")}, es una lista de dos
    elementos. La @c{"p"} le indica a Emacs que debe pasar el argumento
    prefijo a la función y utilizar este valor para el argumento de la
    función.

    El argumento debe ser un número. Esto significa que el símbolo @c{numero}
    estara asociado a un número en la línea:

    ..src > elisp
      (message "El resultado es %d" (* 7 numero))
    < src..

    Por ejemplo, si tu argumento prefijo es 5, el intérprete Lisp evaluará la
    línea como si fuera:

    ..src > elisp
      (message "El resultado es %d" (* 7 5))
    < src..

    (Si estás leyendo esto en GNU Emacs, puedes evaluar esta expresión por ti
    mismo.) Primero, el intérprete evaluará la lista interna, que es @c{(* 7
    5)}. Esto devuelve un valor de 35. A continuación, se evaluará la lista
    externa, pasando los valores del segundo y posteriores elementos de la
    lista a la función @c{message}.

    Como hemos visto, @c{message} es una función Emacs Lisp especialmente
    diseñada para enviar un mensaje de una línea al usuario. (Consulta la Seccion
    @l{#La función @c{message}}.) En resumen, la función @c{message} imprime su
    primer argumento en el área de eco tal cual, excepto para las ocurrencias de
    @'c{%d}, o @'c{%s} (y varias otras secuencias de control que no hemos
    mencionado). Cuando aparece una secuencia de control, la función busca
    el segundo argumento o los siguientes e imprime el valor del argumento en
    la ubicación donde se encuartra la secuencia de control.

    En la función interactiva @c{multiplicar-por-siete}, la cadena de
    control es @'c{%d}, que requiere un número, y el valor devuelto por la
    evaluación de @c{(* 7 5)} es el número 35. Por consiguiente, el número 35
    se imprime en lugar de @'c{%d} y el mensaje es @'{El resultado es 35}.

    (Observa que cuando llamas a la función @c{multiplicar-por-siete}, el
    mensaje se imprime sin comillas, pero cuando llamas a @c{message}, el
    texto se imprime entre comillas. Esto se debe a que el valor devuelto por
    @c{message} aparece en el área de eco cuando se evalúa una expresión cuyo
    primer elemento es @c{message}; pero si se integra en una función,
    @c{message} imprime el texto como un efecto secundario sin las comillas.)

** Diferentes opciones para @c{interactive}

   En el ejemplo, @c{multiplicar-por-siete} utilizo @c{"p"} como el
   argumento para @c{interactive}. Este argumento le indica a Emacs que
   interpretara cualquer cosa que escribas despues de @k{C-u} o del comando
   @k{META} como un numero que sera el argumento a pasar a la funcion. Emacs
   tiene más de veinte caracteres predefinidos para usar con @c{interactive}.
   En casi todos los casos, una de estas opciones te permitira pasar la
   información correcta de forma interactiva a una función. (Consulta la Seccion
   @l{elisp.html#Interactive Codes<>Codigo de Caracteres para @c{interactive}} en @e(El
   Manual de Referencia de GNU Emacs Lisp)).

   Considera la función @c{zap-to-char}. Su expresión interactiva es

   ..src > elisp
     (interactive "p\ncZap to char: ")
   < src..

   La primer parte del argumento de @c{interactive} es @'{p}, con el que ya
   estás familiarizado. Este argumento le dice a Emacs que interprete un
   ‘prefijo’, como un número que se pasa a la función. Puedes especificar un
   prefijo presionando @k{C-u} seguido de un número o igualmente con @k{META}
   seguido por un número. El prefijo es un número de caracteres especifico. De
   este modo, si el prefijo es tres y el caracter especificado es @'{x},
   entonces se borrará todo el texto hasta e incluido el tercer @'{x}
   siguiente. Si no se establece un prefijo, entonces borras todo el texto hasta
   e incluido el carácter especificado, pero no más.

   La @'{c} le dice a la función el nombre del carácter que va a eliminar.

   Más formalmente, una función con dos o más argumentos puede tener
   información que pasa a cada argumento añadiendo partes a la cadena que
   sigue a @c{interactive}. Al hacer esto, la información se
   pasa a cada argumento en el mismo orden que se especifica en la lista
   @c{interactive}. En la cadena, cada parte está separada de la siguente
   parte por un @'{\n}, que significa nueva línea. Por ejemplo, a @'{p} puede
   continuar un @'{\n} y un @'{cZap to char: }. Esto hace que Emacs pase el
   valor del argumento prefijo (si lo hay) y el carácter.

   En este caso, la definición de función se parece a la siguiente, donde
   @c{arg} y @c{char} son los símbolos que @c{interactive} vincula al
   argumento prefijo y el caracter especificado:

   ..src > elisp
     (defun nombre-de-funcion (arg char)
       "documentacion…"
       (interactive "p\ncZap to char: ")
       cuerpo-de-funcion…)
   < src..

   (El espacio después de los dos puntos en el prompt hace que se vea mejor.
   Consulta la Seccion @l{#La Definición de @c{copy-to-buffer}}, para ver un
   ejemplo.)

   Cuando una función no toma argumentos, @c{interactive} no requiere
   ninguno. Una función asi contiene unicamente la expresión
   @c{(interactive)}. La función @c{mark-whole-buffer} es asi.

   Alternativamente, si los códigos de letras especiales no son adecuados
   para tu aplicación, puedes pasar tus propios argumentos a
   @c{interactive} como una lista.

   Consulta la Seccion @l{#La Definición de @c{append-to-buffer}}, para ver un
   ejemplo. Consulta la Sección @l{elisp.html#Using Interactive<>Usando
   @c{interactive}} en @e(El Manual de GNU Emacs Lisp), para una explicación más
   completa sobre esta técnica.

** Instalar Código Permanentemente

   Cuando instalas una definición de función evaluandola, permanecera instalada
   hasta que salgas de Emacs. La proxima vez que inicies una nueva sesión de
   Emacs, la función no sera instalada a menos que evalúes de nuevo la
   definición.

   En algún momento, podrias necesitar que el código se instale
   automáticamente cada vez que inicies una nueva sesión de Emacs. Hay varias
   formas de hacer esto:

   - Si tienes código solo para tu personal, puedes poner el código de la
     definición de función en el fichero de inicialización @f{.emacs}. Cuando se
     inicia Emacs, el fichero @f{.emacs} se evalúa automáticamente y se instalan
     todas las definiciones de función que contiene. Consulta la Sección @l{#Tu
     Fichero @f{.emacs}}.

   - Como Alternativa, puedes poner las definiciones de función en uno o más
     ficheros y usar la función @c{load} para hacer que Emacs evalue y con
     ello instale cada una de las funciones en los ficheros. Consulta la Seccion
     @l{#Cargando ficheros}.

   - En Tercer lugar, si tienes código que todo tu sitio va a utilizar, es
     normal ponerlo en un fichero llamado @f{site-init.el} que se carga
     cuando se construye Emacs. Esto hace que el código este disponible para
     todos los usuarios de tu máquina. (Mira el fichero @f{INSTALL} que forma
     parte de la distribución Emacs.)

   Finalmente, si tienes código que cualquier usuario de Emacs pueda querer,
   puedes publicarlo en una red de computadores o enviar una copia a la Free
   Software Foundation. (Al hacer esto, por favor licencia el código y su
   documentación bajo una licencia que permita a otras personas ejecutar,
   copiar, estudiar, modificar, y redistribuir el código y te proteja de quien
   tome tu trabajo.) Si envias una copia de tu código a la Free Software
   Foundation, y te proteges apropiadamente a ti mismo y a los demas, puede ser
   incluido en la siguiente version de Emacs. En gran parte, esta es la forma
   como ha crecido Emacs a través de los años, gracias a las de donaciones.

** @c{let}

   La expresión @c{let} es una forma especial de Lisp que tendras que
   utilizar en la mayoría de las definiciones de función.

   @c{let} se utiliza para unir o enlazar un símbolo a un valor de tal manera
   que el intérprete no confunda la variable con otra variable del mismo
   nombre que no forme parte de la función.

   Para entender por qué la forma especial @c{let} es necesaria, considera la
   situación donde eres dueño de una casa que generalmente vinculas con ‘la
   casa’, como en la frase, “La casa necesita pintura”. Si visitas a un amigo
   y tu anfitrion hace referencia a ‘la casa’, es probable que se refiera a
   @e{su} casa, no a la tuya, es decir, a una casa diferente.

   Si tu amigo se refiere a su casa y tu crees que el se esta refiriendo a tu
   casa, puedes encontrarte en una situacion confusa. Lo mismo podría suceder en
   Lisp si una variable que se usa dentro de una función tiene el mismo nombre
   que una variable que se utiliza dentro de otra función, y no se pretende que
   ambas se refieran al mismo valor. La forma especial @c{let} permite evitar
   este tipo de confusión.

   La forma especial @c{let} evita confusiones. @c{let} crea un nombre para
   una @:{variable local} que eclipsa cualquier uso del mismo nombre fuera de
   la expresión @c{let}. Esto es como entender que cuando tu anfitrion
   haga referencia a ‘la casa’, el quiere referirse a su casa, no la tuya. (Los símbolos
   usados en las listas de argumentos funcionan de la misma manera. Consulta la
   Sección @l{#La Forma Especial @c{defun}}.)

   Las variable locales creadas por una expresión @c{let} retienen su valor
   @e{solo} dentro de la expresión @c{let} (y dentro de las expresiones
   llamadas dentro de la expresión @c{let}); las variables locales no tiene
   efecto fuera de la expresión @c{let}.

   Otra forma de persar sobre @c{let} es que es como un @c{setq} que es temporal
   y local. Los valores establecidos por @c{let} se deshacen automáticamente
   cuando @c{let} finaliza. La configuración solo afecta a las expresiones que
   se encuentran dentro de los limites de la expresión @c{let}. En la jerga
   informatica, diríamos que “la union de un simbolo solo es visible en las
   funciones llamadas en la forma @c{let}; en Emacs Lisp, el alcance es
   dinámico, no léxico.”

   @c{let} puede crear más de una variable a la vez. Ademas, @c{let} da a cada
   variable que crea un valor inicial, ya sea un valor especificado por tí, o
   @c{nil}. (En la jerga, eso se llama ‘enlazar la variable al valor’.)  Después
   de que @c{let} ha creado y enlazado las variables, ejecuta el código en el
   cuerpo del @c{let} y devuelve el valor de la última expresión en el cuerpo,
   como el valor de toda la expresión @c{let}. (‘Ejecutar’ es un término tecnico
   que significa evaluar una lista; proviene del significando de la palabra
   ‘llevar a la practica’ (@e{Oxford English Dictionary}). Puesto que se evalua una
   expresión para realizar una acción, ‘ejecutar’ ha evolucionado como un
   sinónimo para ‘evaluar’.)

*** Partes de una expresión @c{let}

    Una expresión @c{let} es una lista de tres partes. La primer parte es el
    símbolo @c{let}. La segunda parte es una lista, llamada @:{varlist}
    @%i(lista de variables), cada uno de cuyos elementos es un símbolo por sí
    mismo o una lista de dos elementos, cuyo primer elemento es un símbolo. La
    tercer parte de la expresión @c{let} es el cuerpo de @c{let}. El cuerpo
    normalmente consiste de una o más listas.

    Una plantilla de la expresión @c{let} se veria asi:

    ..src > elisp
      (let varlist cuerpo…)
    < src..

    Los símbolos de la lista de varibles @%c(varlist) son las variables a las
    que la forma especial @c{let} da valores de inicio. A los símbolos por si
    mismos se les da el valor inicial @c{nil}; y cada símbolo que sea el primer
    elemento de una lista de dos elementos se vincula al valor que se devuelve
    cuando el interprete Lisp evalúa el segundo elemento.

    Por lo tanto, una varlist podria verse asi: @c{(hilo (agujas 3))}. En
    este caso, en una expresión @c{let}, Emacs une el símbolo @c{hilo} a
    un valor inicial de @c{nil}, y une el símbolo @c{agujas} a un valor inicial
    de 3.

    Cuando escribes una expresión @c{let}, lo que haces es poner las
    expresiones apropiadas en los espacios de la plantilla de la expresión
    @c{let}.

    Si la varlist está compuesta de listas de 2 elementos, como suele ser el
    caso, la plantilla de la expresión @c{let} se ve asi:

    ..src > elisp
      (let ((variable valor)
            (variable valor)
            …)
        cuerpo…)
    < src..

*** Ejemplo de Expresión @c{let}

    La siguiente expresión crea y da valores iniciales a las dos variables
    @c{cebra} y @c{tigre}. El cuerpo de la expresión @c{let} es una lista que
    llama a la función @c{message}.

    ..src > elisp
      (let ((cebra 'rayas)
            (tigre 'fiero))
        (message "Un tipo de animal tiene %s y otro es %s."
                 cebra tigre))
    < src..

    Aquí, la varlist es @c{((cebra 'rayas) (tigre 'fiero))}.

    Las dos variables son @c{cebra} y @c{tigre}. Cada variable es el primer
    elemento de una lista de dos elementos y cada valor es el segundo
    elemento de su lista de dos elementos. En la varlist, Emacs une la
    variable @c{cebra} al valor @c{rayas}@n{8}, y la variable @c{tigre}
    al valor @c{fiero}. En este ejemplo, ambos valores son símbolos
    precedidos por una cita. Los valores podrían muy bien haber sido otra
    lista o una cadena. El cuerpo de @c{let} sigue después de la lista que
    contiene las variables. En este ejemplo, el cuerpo es una lista que usa
    la función @c{message} para imprimir una cadena en el área de eco.

    Puedes evaluar el ejemplo de la forma habitual, colocando el cursor después
    del último paréntesis y presionando @k{C-x C-e}. Al hacer esto, aparecerá lo
    siguiente en el área de eco:

    ..src > elisp
      "Un tipo de animal tiene rayas y otro es fiero."
    < src..

    Como hemos visto anteriormente, la función @c{message} imprime su primer
    argumento, excepto @'{%s}. En este ejemplo, el valor de la variable
    @c{cebra} se imprime en la ubicacion del primer @'{%s} y el valor de la
    variable @c{tigre} se imprime en la ubicacion del segundo @'{%s}.

*** Variables sin inicializar en un sentencia @c{let}

    Si no se unen las variables en una sentencia @c{let} con valores
    de inicio específicos, automáticamente seran enlazados a un valor de inicio
    @c{nil}, como en la siguiente expresión:

    ..src > elisp
      (let ((abedul 3)
            pino
            abeto
            (roble 'algunos))
        (message "Aquí están %d variables con %s, %s, y el valor %s."
                 abedul pino abeto roble))
    < src..

    Aquí, la varlist es @c{((abedul 3) pino abeto (roble 'algunos))}.

    Si evalúas esta expresión de la forma habitual, aparecerá lo siguiente en
    el área de eco:

    ..example >
      "Aquí están 3 variables con nil, nil, y el valor algunos."
    < example..

    En este ejemplo, Emacs une el símbolo @c{abedul} al número 3, une los
    símbolos @c{pino} y @c{abeto} a @c{nil}, y el símbolo @c{roble} al
    valor @c{algunos}.

    Observa que en la primer parte de @c{let}, las variables @c{pino} y
    @c{abeto} son unicamente átomos que no están rodeados por paréntesis;
    esto es porque estan siendo ligados a @c{nil}, la lista vacía. Pero
    @c{roble} su une a @c{algunos} por que es parte de la lista @c{(roble
    'algunos)}. De manera similar, @c{abedul} se une al número 3 en una lista
    con este número. (Ya que un número se evalúa a sí mismo, no es necesario
    citar el numero. Ademas, el número se imprime en el mensaje
    utilizando un @'c{%d} en lugar de un @'c{%s}.) Las cuatro variables como
    grupo se ponen en una lista para delimitarlas del cuerpo de @c{let}.

** La forma especial @c{if}

   Además de @c{let} y @c{defun}, esta la forma especial condicional @c{if}.
   Esta forma se utiliza para indicar al ordenador que tome decisiones.
   Puedes escribir definiciones de función sin necesidad de utilizar @c{if},
   pero se usa con bastante frecuencia, y es lo suficientemente importante
   como para incluirla aquí. Se utiliza, por ejemplo, en el código de la
   función @c{beginning-of-buffer}.

   La idea básica detras de @c{if}, es que “@e{si} @%i(if) una prueba es verdadera
   @e{entonces} @%i(then) se evalua la expresión”. Si la prueba no es verdadera, la
   expresión no se evalua. Por ejemplo, podrías tomar una decisión como, “si
   hace sol y calor, entonces ve a la playa!”

   Al escribir una expresión @c{if} en Lisp no se utiliza la palabra ‘entonces’;
   la prueba y la acción son los elementos segundo y tercero de la lista cuyo
   primer elemento es @c{if}. No obstante, la parte de la prueba en una
   expresión @c{if} a menudo se llamada @:{parte-si} @%i(if-part) y el segundo
   argumento a menudo se llamada @:{parte-entonces} @%i(then-part).

   Ademas, cuando se escribe una expresión @c{if}, la prueba-verdadero-o-falso
   normalmente se escribe en la misma línea que el símbolo @c{if}, pero la
   acción a llevar a cabo si la prueba es verdadera, “parte-entonces”, se
   escribe en la segunda y suguientes líneas. Esto hace que la expresión @c{if}
   sea mas fácil de leer.

   ..src > elisp
     (if prueba-verdadero-o-falso
         accion-a-realizar-si-la-prueba-es-verdadera)
   < src..

   La prueba-verdadero-o-falso es una expresión que evalua el intérprete
   Lisp.

   Aquí hay un ejemplo que puedes evaluar. La prueba consiste en si el número
   5 es mayor que el número 4. Puesto que es asi, se imprime el mensaje @'{¡5 es
   mayor que 4!}.

   ..src > elisp
     (if (> 5 4)                           ; parte-si
         (message "¡5 es mayor que 4!"))   ; parte-entonces
   < src..

   (La función @c{>} comprueba si su primer argumento es mayor que su segundo
   argumento y devuelve verdadero si lo es.)

   Por supuesto, en un caso real, la prueba en una expresión @c{if} no será
   fija eternamente, como en la expresión @c{(> 5 4)}. En su lugar, al menos
   una de las variables utilizadas en la prueba estara unida a un valor de
   antemano desconocido. (Si el valor se conociera de antemano, ¡no necesitariamos
   realizar la prueba!)

   Por ejemplo, el valor puede estar unido a un argumento de una definición
   de función. En la siguiente definición de función, el tipo de animal es un
   valor que se pasa a la función. Si el valor unido a @c{caracteristica} es
   @c{fiero}, entonces se imprime el mensaje, @'{¡Es un tigre!}; de otro
   modo, se devolvera @c{nil}.

   ..src > elisp
     (defun tipo-de-animal (caracteristica)
       "Imprime el mensaje en el área de eco dependiendo de CARACTERISTICA.
     Si la CARACTERISTICA es el símbolo ‘fiero’,
     entonces advierte que es un tigre."
       (if (equal caracteristica 'fiero)
           (message "¡Es un tigre!")))
   < src..

   Si estás leyendo esto dentro de GNU Emacs, puedes evaluar la definición de
   función de la forma habitual para instalarla en Emacs, y luego puedes
   evaluar las siguientes dos expresiones para ver los resultados:

   ..src > elisp
     (tipo-de-animal 'fiero)

     (tipo-de-animal 'cebra)
   < src..

   Al evaluar @c{(tipo-de-animal 'fiero)}, veras el siguiente mensaje impreso
   en el área de eco: @c{"¡Es un tigre!"}; y cuando se evalúa @c{(tipo-de-animal
   'cebra)} verás @c{nil} impreso en el área de eco.

*** La función @c{tipo-de-animal} en detalle

    Veamos en detalle la función @c{tipo-de-animal}.

    La definición de función @c{tipo-de-animal} se escribio llenando los
    espacios de dos plantillas, una para la definición de función como
    un todo, y otra para una expresión @c{if}.

    La plantilla para toda función no interactiva es:

    ..src > elisp
      (defun nombre-de-funcion (lista-de-argumentos)
        "documentacion…"
        cuerpo…)
    < src..

    Las partes de la función que coinciden con esta plantilla tienen el siguiente aspecto:

    ..src > elisp
      (defun tipo-de-animal (caracteristica)
        "Imprime el mensaje en el área de eco dependiendo de CARACTERISTICA.
      Si la CARACTERISTICA es el símbolo ‘fiero’,
      entonces advierte que es un tigre."
        cuerpo: la expresion if)
    < src..

    El nombre de función es @c{tipo-de-animal}; se le pasa el valor de un
    argumento. A la lista de argumentos le sigue una cadena de documentación
    multilínea. La cadena de documentación se incluiye en el ejemplo porque
    es un buen hábito escribir un cadena de documentación para cada
    definición de función. El cuerpo de la definición de función consiste en
    la expresión @c{if}.

    La plantilla de una expresión @c{if} se ve así:

    ..src > elisp
      (if prueba-verdadero-o-falso
          accion-a-realizar-si-la-prueba-devuelve-verdadero)
    < src..

    En la función @c{tipo-de-animal}, el código para el @c{if} se ve así:

    ..src > elisp
      (if (equal caracteristica 'fiero)
          (message "¡Es un tigre!")))
    < src..

    Aquí, está la expresión prueba-verdadero-o-falso

    ..src > elisp
      (equal caracteristica 'fiero)
    < src..

    En Lisp, @c{equal} es una función que determina si su primer argumento es
    igual al segundo. El segundo argumento es el símbolo citado @c{'fiero} y el
    primer argumento es el valor del símbolo @c{característica}––en otras
    palabras, el argumento pasado a esta función.

    En la primer prueba de @c{tipo-de-animal}, el argumento @c{fiero} se pasa
    a @c{tipo-de-animal}. Ya que @c{fiero} es igual a @c{fiero}, la
    expresión, @c{(equal caracteristica 'fiero)}, devuelve el valor
    verdadero. Cuando esto sucede, @c{if} evalúa el segundo argumento o la
    parte-entonces del @c{if}: @c{(message "¡Es un tigre!")}.

    Por otro lado, en la segunda prueba de @c{tipo-de-animal}, se pasa el
    argumento @c{cebra} a @c{tipo-de-animal}. @c{cebra} no es igual a @c{fiero},
    por lo que la parte-entonces no se evalua y la expresión @c{if} devuelve
    @c{nil}).

** Expresiones if–then–else

   Una expresión @c{if} puede tener un tercer argumento opcional, llamado
   @:(parte-de-otro-modo) @%i{else-part}, en caso de que la
   prueba-verdadero-o-falso devuelva falso. Cuando esto sucede, el segundo
   argumento o parte-entonces de la expresión @c{if} global @e{no} se evalúa, pero
   el tercer argumento o parte-de-otro-modo @e{se} evalúa. Podrías pensar en
   esto como la alternativa del día nublado para la decisión “si es cálido y
   soleado, entonces ir a la playa!, de otro modo leer un libro!”

   La palabra “else” @%i(de otro modo) no se escribe en el código Lisp; la
   parte-de-otro-modo de una expresión @c{if} viene después de la
   parte-entonces. En Lisp, la parte-de-otro-modo suele escribirse al inicio
   de una nueva linea y tiene menos indentacion que la parte-entonces:

   ..src > elisp
     (if prueba-verdadero-o-falso
         accion-a-realizar-si-la-prueba-devuelve-verdadero
       accion-a-realizar-si-la-prueba-devuelve-falso)
   < src..

   Por ejemplo, evaluar la siguiente expresión @c{if} imprime el mensaje @'{¡4 no es
   mayor que 5!}:

   ..src > elisp
     (if (> 4 5)                                   ; parte-if
         (message "¡4 falsamente es mayor que 5!") ; parte-then
       (message "¡4 no es mayor que 5!"))          ; parte-else
   < src..

   Observa que los diferentes niveles de indentación hacen fácil distinguir la
   parte-entonces (por brevedad, y mezclando ingles con español, apartir de
   ahora @%i(parte-then)) de la parte-de-otro-modo (por brevedad, y mezclando
   ingles con español, apartir de ahora @%i(parte-else)). (GNU Emacs tiene
   varios comandos que indentan expresiones @c{if} automáticamente. Consulta la
   Seccion @l{#GNU Emacs te ayuda a escribir listas}.)

   Podemos ampliar la función @c{tipo-de-animal} para incluir una parte-else
   simplemente incorporando una parte adicional a la expresión @c{if}.

   Puedes ver las consecuencias de hacer esto si evalúas la siguiente versión de
   la función @c{tipo-de-animal} y luego evaluas las dos expresiones siguientes
   que pasan argumentos diferentes a la función.

   ..src > elisp
     (defun tipo-de-animal (caracteristica)
       "Imprime un mensaje en el área de eco dependiendo de la CARACTERISTICA.
     Si la CARACTERISTICA es el símbolo ‘fiero’,
     entonces advierte que es un tigre.
     de otro modo dice que no es fiero"
       (if (equal caracteristica 'fiero)
           (message "¡Es un tigre!")
         (message "!No es feroz!")))

     (tipo-de-animal 'fiero)

     (tipo-de-animal 'cebra)
   < src..

   Cuando evalues @c{(tipo-de-animal 'fiero)}, verás el siguiente mensaje en el
   área de eco: @c{"¡Es un tigre!"}; cuando evalues @c{(tipo-de-animal
   'cebra)}, verás @c{"¡No es feroz!"}.

   (Por supuesto, si @c{característica} fuera @c{muy-feroz}, se imprimiria el
   mensaje @c{"¡No es feroz!"}; ¡y sería un error!  Cuando escribas código,
   debes tener en cuenta la posibilidad de que algun argumento como este
   sea probado por @c{if} y acorde a ello escribir tu programa.

** Verdad y Falsedad en Emacs Lisp

   Hay un aspecto importante para probar la verdad en una expresión
   @c{if}. Hasta ahora, hemos hablado de ‘verdadero’ y ‘falso’ como valores
   de predicados como si fueran nuevos tipos de objetos Emacs Lisp. De hecho,
   solo nuestro viejo amigo @c{nil} es ‘falso’. Cualquier otra
   cosa––cualquiera en absoluto––es ‘verdadero’.

   La expresión que prueba si algo es verdadero se interpreta como @:{true}
   @%i(verdadero) si el resultado de la evaluacion es no @c{nil}. En otras
   palabras, el resultado de la prueba se considera verdadero si el valor
   devuelto es un número como 47, una cadena como @c{"hola"}, o un símbolo
   (distinto de @c{nil}) como @c{flores}, o una lista (siempre y cuando no
   este vacía) o incluso ¡un búfer!

   Antes de ilustrar una prueba para verdadero, necesitamos una explicación
   de @c{nil}.

   En Emacs Lisp, el símbolo @c{nil} tiene dos significados. En primer lugar,
   significa que la lista está vacía. En segundo lugar, significa falso y es
   el valor devuelto cuando una prueba-verdadero-o-falso obtiene falso.
   @c{nil} puede escribirse como una lista vacia, @c[()], o como @c(nil). En
   lo referente al interprete Lisp @c[()] y @c(nil) son lo mismo. Los
   humanos, sin embargo, tienden a usar @c{nil} para falso y @c{()} para
   lista vacía.

   En Emacs Lisp, cualquier valor que no sea @c{nil}––si no es una lista
   vacía––se considera verdadero. Esto significa que si una evaluación devuelve
   algo que no es una lista vacía, una expresión @c{if} probara ser
   verdadera. Por ejemplo, si un número se coloca en el lugar de la prueba, se
   evaluara y devolverá su valor, ya que eso es lo que hacen los números cuando
   se evalúan. En esta condicion, la expresión @c{if} pasara su prueba como
   verdadero. La expresión pasara su prueba como falsa solo cuando @c{nil}, o
   una lista vacía, son devueltas al evaluar la expresión.

   Puedes ver esto evaluando las dos expresiones en los ejemplos siguientes.

   En el primer ejemplo, el número 4 se evalua como la prueba en la expresión
   @c{if} y se devuelve a si mismo; en consecuencia, se evalua y devuelve
   la parte-then de la expresión: aparece @'{verdadero} en el área de eco. En el
   segundo ejemplo, @c{nil} indica falso; en consecuencia, se evalua y
   devuelve la parte-else de la expresión: aparece @'{falso} en el área de eco.

   ..src > elisp
     (if 4
         'verdadero
       'falso)

     (if nil
         'verdadero
       'falso)
   < src..

   Por cierto, si algún otro valor de utilidad no está disponible para una prueba
   que devuelve verdadero, entonces el intérprete Lisp devolvera el símbolo
   @c{t} para verdadero. Por ejemplo, la expresión @c{(> 5 4)} devuelve @c{t}
   cuando se evalúa, como puedes comprobar si evaluas:

   ..src > elisp
     (> 5 4)
   < src..

   Por otra parte, esta función devuelve @c{nil} si la prueba es falsa.

   ..src > elisp
     (> 4 5)
   < src..

** @c{save-excursion}

   La función @c{save-excursion} es la cuarta y última forma especial que
   discutiremos en este capítulo.

   En los programas Emacs Lisp utilizados para la edición, la función
   @c{save-excursion} es muy común. Guarda la posición del punto y marca,
   ejecuta el cuerpo de la función, y luego restaura el punto y marca a sus
   posiciones previas si sus posiciones fueron cambiadas. Su proposito
   principal es impedir que el usuario se sorprenda y perturbe por el
   movimiento inesperado del punto o marca.

   Sin embargo, antes de hablar de @c{save-excursion}, puede ser útil examinar
   primero que son el punto y la marca en GNU Emacs. @:{Punto} es la posición
   actual del cursor. Donde sea que se encuentre el cursor, estara el punto. De
   forma más precisa, en los terminales donde el cursor aparece sobre un
   carácter, el punto se encuentra inmediatamente antes del carácter. En Emacs Lisp, el
   punto es un numero entero. El primer carácter en un búfer es el número uno,
   el segundo es el número dos, y así sucesivamente. La función @c{point}
   devuelve la posición actual del cursor como un número. Cada búfer tiene su
   propio valor para el punto.

   La @:{marca} es otra posición en el búfer; su valor se puede establecer con
   un comando como @k{C-SPC} @%c(set-mark-command). Si se ha establecido una
   marca, puedes utilizar el comando @k{C-x C-x} @%c(exchange-point-and-mark)
   para hacer que el cursor salte a la marca y establecer la marca como la
   posición anterior del punto. Además, si se establece otra marca, la posición
   de la marca anterior se guarda en el anillo de marcas. Muchas posiciones de
   marca se pueden guardar de esta manera. Se puede mover el cursor a una marca
   guardada presionando @k{C-u C-SPC} una o más veces.

   La parte del búfer entre el punto y la marca se denomina @:{la región}.
   Numerosos comandos trabajan en la región, incluyendo @c{center-region},
   @c{count-lines-region}, @c{kill-region} y @c{print-region}.

   La forma especial @c{save-excursion} guarda las ubicaciones del punto y la
   marca y restaura estas posiciones después de que el interprete Lisp evalua el
   código dentro del cuerpo de la forma especial. De este modo, si el punto
   se encontraba al inicio de un texto y algún código moviera el
   punto al final del búfer, @c{save-excursion} volvera a poner el punto
   donde estaba antes, luego que las expresiones en el cuerpo de la funcion
   fueran evaluadas.

   En Emacs, una función se mueve con frecuencia de punto a otro como parte de
   su funcionamiento interno, aunque el usuario no lo espere. Por
   ejemplo, @c{count-lines-region} mueve el punto. Para evitar que el usuario
   sea molestado por saltos inesperados y (desde el punto de vista del usuario)
   innecesarios, @c{save-excursion} se utiliza a menudo para conservar el punto
   y la marca en la posición esperada por el usuario. El uso de
   @c{save-excursion} es bueno para mantener el orden.

   Para asegurarse que la casa se mantiene limpia, @c{save-excursion}
   restaura los valores del punto y la marca incluso si algo va mal con el
   código en su cuerpo (o, para ser más preciso y usar el lenguaje tecnico
   apropiado, “en caso de salida anormal”). Esta caracteristica es muy útil.

   Además de registrar los valores del punto y marca, @c{save-excursion}
   mantiene un registro del buffer actual, y tambien lo restaura. Esto significa que
   puedes escribir código que cambie de bufer y @c{save-excursion} lo devuelva
   al bufer original. Asi es como se utiliza @c{save-excursion} en
   @c{append-to-buffer}.  (Consulta la Seccion @l{#La Definición de
   @c{append-to-buffer}}.)

*** Plantilla para una Expresión @c{save-excursion}

    La plantilla de código usando @c{save-excursion} es simple:

    ..src > elisp
      (save-excursion
        cuerpo…)
    < src..

    El cuerpo de la función es una o más expresiones que serán evaluadas de
    forma secuencial por el intérprete Lisp. Si hay más de una expresión en
    el cuerpo, el valor de la última será devuelto como el valor de la
    función @c{save-excursion}. Las otras expresiones en el cuerpo solo se
    evaluan por sus efectos secundarios; y @c{save-excursion} en misma solo se
    utiliza por su efecto secundario (que es restaurar las posiciones del
    punto y la marca).

    La siguiente plantilla explica @c{save-excursion}, con más detalle:

    ..src > elisp
      (save-excursion
        primera-expresion-en-el-cuerpo
        segunda-expresion-en-el-cuerpo
        tercera-expresion-en-el-cuerpo
         …
        ultima-expresion-en-el-cuerpo)
    < src..

    Una expresión, por supuesto, puede ser un símbolo por sí mismo o una
    lista.

    En el código Emacs Lisp, una expresión @c{save-excursion} a menudo ocurre
    dentro del cuerpo de una expresión @c{let}. Tiene un aspecto algo asi:

    ..src > elisp
      (let varlist
        (save-excursion
          cuerpo…))
    < src..

** Repaso: Cómo escribir definiciones de funcion <> Repaso

   En los últimos capítulos se han introducido un buen número de funciones y
   formas especiales. A continuacion se describen brevemente, junto con
   algunas funciones similares que aun no se han mencionado.

   - @c(eval-last-sexp) ::

     Evalúa la última expresión simbólica antes de la posición actual del
     punto. El valor se imprime en el área de eco a menos que la función se
     invoque con un argumento; en este caso, la salida se imprime en el
     búfer actual. Este comando normalmente esta ligado a @k{C-x C-e}.

   - @c(defun) ::

     Define una función. Esta forma especial consta de hasta cinco partes: el
     nombre, una plantilla para los argumentos que se pasan a la función, la
     documentacion, una declaración interactiva opcional, y el cuerpo de la
     definición.

     Por ejemplo, en las primeras versiones de Emacs, la definición de la
     función @c(back-to-indentation) era la siguiente. (Es ligeramente más
     compleja ahora que busca el primer caracter que no es espacio en lugar
     del primer caracter visible.)

     ..src > elisp
       (defun back-to-indentation ()
         "Mueve el punto al primer caracter visible de la linea."
         (interactive)
         (beginning-of-line 1)
         (skip-chars-forward " \t"))
     < src..

   - @c(interactive) ::

     Anuncia al intérprete que la función se puede usar de forma interactiva.
     Esta forma especial puede ir seguida de una cadena con una o más
     partes que pasan la información a los argumentos de la función, de forma
     secuencial. Estas partes pueden también decir al intérprete que solicite
     información. Las partes de la cadena estan separadas por saltos de
     linea, @'{\n}.

     Los codigos de caractere comúnes son:

     - @c(b): El nombre de un búfer existente.

     - @c(f): El nombre de un fichero existente

     - @c(p): El argumento prefijo numérico. (Observa que esta ‘p’ es minúscula.)

     - @c(r): El punto y la marca, como dos argumentos numéricos, el más pequeño
       primero. Este es el unico codigo de una letra que especifica dos
       argumentos sucesivos en lugar de uno.

     Consulta la Seccion @l{elisp.html#Interactive Codes<>Codigo de caracteres para
     @'{interactive}} en @e(El Manual de Referencia de GNU Emacs Lisp), para
     obtener una lista completa de los codigos de caracteres.

   - @c(let) ::

     Declara una lista de variables para utilizarla dentro del cuerpo de
     @c{let} y darle a cada variable un valor inicial, ya sea @c{nil} o un valor
     específicado; luego evalua el resto de las expresiones en el cuerpo del
     @c{let} y devuelve el valor de la última expresion. Dentro del cuerpo
     del @c{let}, el intérprete Lisp no ve los valores de las variables con el
     mismo nombre declaradas fuera de @c{let}.

     Por ejemplo,

     ..src > elisp
       (let ((foo (buffer-name))
             (bar (buffer-size)))
         (message "Este buffer es %s y tiene %d caracteres."
                  foo bar))
     < src..

   - @c(save-excursion) ::

     Registra los valores de punto, marca y del búfer actual antes de evaluar el
     cuerpo de esta forma especial. Tras evaluar su cuerpo, restaura los valores
     de punto, marca y búfer.

     Por ejemplo,

     ..src > elisp
       (message "Estamos %d caracteres dentro de este buffer."
                (- (point)
                   (save-excursion
                     (goto-char (point-min))
                     (point))))
     < src..


   - @c(if) ::

     Evalúa el primer argumento de la función; si es verdadero, evalúa el
     segundo argumento; de otra forma evalúa el tercer argumento, si lo hay.

     La forma especial @c{if} se llamada @:{condicional}. Hay otros
     condicionales en Emacs Lisp, pero @c{if} es quizás el más utilizado.

     Por ejemplo,

     ..src > elisp
       (if (= 24 emacs-major-version)
           (message "Esta es la version 24 de Emacs")
         (message "Esta no es la version 24 de Emacs"))
     < src..

   - @c(<), @c(>), @c(<=), @c(>=) ::

     La función @c{<} prueba si su primer argumento es menor que el segundo.
     @c{>}, prueba si el primer argumento es mayor que el segundo. Del mismo
     modo, @c{<=} prueba si el primer argumento es menor o igual al segundo y
     @c{>=} si el primer argumento es mayor o igual al segundo. En todos los
     casos, ambos argumentos deben ser números o marcadores (los marcadores
     indican posiciones en búfers).

   - @c(=) ::

     La función @c{=} prueba si dos argumentos, ambos números o marcadores,
     son iguales.

   - @c(equal), @c(eq) ::

     Prueban si dos objetos son el mismo. @c{equal} utiliza un signicado de la
     palabra ‘mismo’ y @c{eq} utiliza otro: @c{equal} devuelve verdadero si
     los dos objetos tienen una estructura y contenidos similares, por
     ejemplo, dos copias del mismo libro. Por otro lado, @c{eq}, devuelve
     verdadero si ambos argumentos son realmente el mismo objeto.

   - @c(string<), @c(string-lessp), @c(string=), @c(string-equal) ::

     La función @c{string-lessp} prueba si su primer argumento es menor que el
     segundo. Un nombre alternativo mas corto para la misma función (un
     @c{defalias}) es @c{string<}.

     Los argumentos para @c{string-lessp} deben ser cadenas o símbolos; la
     ordenación es lexicográfica, por lo que mayusculas o minusculas son
     significativas. Los nombres impresos de símbolos se utilizan en lugar de
     los símbolos mismos.

     Una cadena vacía, @'c{""}, una cadena sin caracteres, es más pequeña que
     cualquier cadena de caracteres.

     @c{string-equal} proporciona la prueba correpondiente para la igualdad.
     Su nombre alternativo es @c{string=}. No hay funciones de prueba
     de cadenas que correspondan a @c{>}, @c{>=} o @c{<=}.

   - @c(message) ::

     Imprime un mensaje en el área de eco. El primer argumento es una cadena
     que puede contener, @'c{%s}, @'c{%d}, o @'c{%c} para imprimir el valor de
     los argumentos que siguen a la cadena. El argumento utilizado por
     @'c{%s} debe ser una cadena o un simbolo, el argumeto utilizado por
     @'c{%d} debe ser un número. El argumento usado por @'c{%c} debe ser un
     codigo númerico @A{ASCII}; se imprimira como el caracter con ese código
     @A{ASCII}. (No se han mencionado otras secuencias @"(porcentuales) @c(%-)).

   - @c(setq), @c(set) ::

     La función @c{setq} asigna al valor de su primer argumento el valor del
     segundo argumento. El primer argumento se cita automáticamente por
     @c{setq}. Hace lo mismo para los pares sucesisvos de argumentos. La
     función, @c{set}, toma solo dos argumentos y evalúa ambos antes de
     asignar el valor devuelto por su primer argumento al valor devuelto por
     el segundo argumento.

   - @c(buffer-name) ::

     Sin un argumento, devuelve el nombre del búfer, como una cadena.

   - @c(buffer-file-name) ::

     Sin un argumento, devuelve el nombre del fichero del búfer que se esta
     visitando.

   - @c(current-buffer) ::

     Devuelve el búfer en el que Emacs se encuentra activo; Puede que no sea
     el búfer que es visible en la pantalla.

   - @c(other-buffer) ::

     Devuelve el ultimo búfer seleccionado mas recientemente (distinto del
     buffer pasado a @c{other-buffer} como un argumento y distinto del búfer
     actual).

   - @c(switch-to-buffer) ::

     Selecciona un búfer de Emacs para activarlo y mostralo en la ventana
     actual para que los usuarios puedan verlo. Normalmente ligado a @k{C-x b}.

   - @c(set-buffer) ::

     Cambiar la atención de Emacs a un búfer en el que se ejecutaran
     los programas. No altera lo que muestra la ventana.

   - @c(buffer-size) ::

     Devuelve el número de caracteres en el búfer actual.

   - @c(point) ::

     Devuelve el valor de la posicion actual del cursor, como un entero
     contando el número de caracteres desde el inicio del búfer.

   - @c(point-min) ::

     Devuelve el valor mínimo admisible del punto en el búfer actual. Esto
     es 1, a menos que narrowing esté activo

   - @c(point-max) ::

     Devuelve el valor máximo admisible del punto en el búfer actual.
     Este es el fin del búfer, a menos que narrowing este activo.

** Ejercicios

   - Escribe una función no interactiva que duplique el valor de su
     argumento, un número. Luego haz la función interactiva.

   - Escribe una función que compruebe si el valor actual de @c{fill-column}
     es mayor que el argumento pasado a la función, y si es así, imprime un
     mensaje apropiado.

* Algunas funciones relacionadas al búfer

  En este capítulo estudiamos en detalle varias de las funciones usadas en GNU
  Emacs. Esto se denomina “walk-through” @%i(recorrido) (visita o demostracion
  de un area o tarea). Estas funciones se utilizan como ejemplos de código Lisp,
  pero no son ejemplos imaginarios; con excepción del primero, con la definición
  de función simplificada, estas funciones muestran el código real usado en GNU
  Emacs. Se puede aprender mucho de estas definiciones. Las funciones aquí
  descritas están relacionadas a los búfers. Mas tarde, estudiaremos otras
  funciones.

** Buscar Más Información

   En este @"(recorrido), describire cada nueva función a medida que lleguemos a
   ella, a veces en detalle y a veces brevemente. Si estás interesado, puedes
   obtener la documentación completa de cualquier función de Emacs Lisp en
   cualquier momento presionando @k{C-h f} y luego ingresando el nombre de la función
   (y luego @k{RET}). Del mismo modo, se puede obtener la documentación completa
   de una variable con @k{C-h v}, luego el nombre de la variable (y despues
   @k{RET}).

   Ademas, @c{describe-function} te dira la ubicacion de la definición de la
   función.

   Coloca el punto sobre el nombre del fichero que contiene la función y
   presiona la tecla @k{RET}. En este caso, @k{RET} significa @c{push-button}
   en lugar de ‘return’ o ‘enter’. Emacs te llevara directamente a la
   definición de la función.

   De manera más general, si quieres ver una función en su fichero fuente
   original, puedes utilizar la función @c{find-tag} para saltar a la misma.
   @c{find-tag} trabaja con una amplia variedad de lenguajes, no solo Lisp, y C,
   y tambien funciona con texto en general. Por ejemplo, @c{find-tag} saltará a
   los distintos nodos del codigo fuente de este documento. La función
   @c{find-tag} depende de ‘tablas de etiquetas’ que registran las ubicaciones
   de las funciones, variables, y otros elementos a los que @c{find-tag} salta.

   Para usar el comando @c{find-tag}, presiona @k{M-.} (es decir, presiona la
   tecla punto mientras presionas la tecla @k(META), o presiona @k{ESC} y
   luego la tecla punto), a continuacion, en el prompt, escribe el nombre de
   la función para ver su código fuente, por ejemplo @c{mark-whole-buffer}, y
   luego pulsa @k{RET}. Emacs cambiará de búfer y mostrará el código fuente
   de la función en la pantalla. Para regresar a tu búfer actual, presiona
   @k{C-x b RET}. (En algunos teclados, la tecla @k{META} se etiqueta como
   @k{ALT}.)

   Dependiendo de la configuracion de los valores iniciales predeterminados de
   tu copia de Emacs, puede ser necesario especificar la posición de tu ‘tabla
   de etiquetas’, que es un fichero llamado @f{TAGS}. Por ejemplo, si estás
   interesado en el codigo fuente de Emacs, lo mas probable es que la tabla de
   etiquetas que deseas, si ya ha sido creada, este en un subdirectorio del
   directorio @f{/usr/local/share/emacs}; de este modo se usaría el comando
   @c{M-x visit-tags-table} y se especificaria una ruta como
   @f{/usr/local/share/emacs/24.1.1/lisp/TAGS}. Si la tabla de etiquetas no ha
   sido creada, tendrás que crearla por tí mismo. Estara en un fichero como
   @f{/usr/local/src/emacs/src/TAGS}.

   Para crear un fichero @f{TAGS} en un directorio específico, cambia a ese
   directorio en Emacs utilizando el comando @k{M-x cd}, o lista el directorio
   con @k{C-x d} @%c(dired). A continuacion ejecuta el comando @c(compile), con
   @c{etags *.el} asi:

   ..example >
     M-x compile RET etags *.el RET
   < example..

   Para más información, consulta la Seccion @l{#Crea tu propio fichero @f{TAGS}}.

   Después de que te familiarices con Emacs Lisp, encontrarás que utilizas con
   frecuencia @c{find-tag} como metodo para navegar por el código fuente; y
   crearás tus propias tablas @f{TAGS}.

   Por cierto, los ficheros que contienen código Lisp se denominan
   convencionalmente @:{librerías}. La metáfora se deriva que una librería
   especializada, como una librería de leyes o una librería de
   ingeniería, en lugar de una librería general. Cada librería, o fichero,
   contiene funciones que se relacionan con un tema o actividad particular,
   por ejemplo @f{abbrev.el} para manejar abreviaturas y atajos, y
   @f{help.el} para la ayuda en linea. (Algunas veces varias librerías
   proporcionan código para una sola actividad, como los distintos ficheros
   @f{rmail…}  que proporcionan codigo para leer correo electrónico.) En @e{El
   Manual de GNU Emacs}, verás frases como “El comando @k{C-h p} te
   permite buscar las librerias estándar de Emacs Lisp por palabras clave
   del tema.”

** Una definición simplificada de @c{beginning-of-buffer}

   El comando @c{beginning-of-buffer} es una buena función para empezar, ya
   que es probable que estes familiarizado con ella y es fácil de
   entender. Utilizado como un comando interactivo, @c{beginning-of-buffer} mueve
   el cursor al inicio del búfer, dejando la marca en la posición
   anterior. Esta generalmente ligado a @k{M-<}.

   En esta sección, discutiremos una versión reducida de la función que
   muestra como se utiliza con mayor frecuencia. Esta función reducida
   funciona como esta escrita, pero no contiene código para una opcion
   compleja. En otra sección, describiremos la función completa. (Consulta la Seccion
   @l(#Definición completa de @c{beginning-of-buffer}).

   Antes de mirar el código, consideremos lo que debe contener la definición de
   función: debe incluir una expresión que haga que la función sea interactiva
   para que puede llamarse tecleando @k{M-x beginning-of-buffer} o pulsando algun
   atajo como @k{M-<}; debe incluir código para dejar una marca en la posición
   original del búfer; y debe incluir código para mover el cursor al inicio del
   búfer.

   Aquí está el texto completo la versión reducida de la función:

   ..src > elisp
     (defun beginning-of-buffer-simplificado ()
       "Mueve el punto al inicio del buffer;
     deja la marca en la posicion anterior."
       (interactive)
       (push-mark)
       (goto-char (point-min)))
   < src..

   Como todas las definiciones de función, esta definición tiene
   cinco partes que siguen la forma especial @c{defun}:

   1. El nombre: en este ejemplo, @c{beginning-of-buffer-simplificado}.

   2. Una lista de argumentos: en este ejemplo, una lista vacía, @c{()},

   3. La cadena de documentación.

   4. La expresión interactiva.

   5. El cuerpo.


   En esta definición de función, la lista de argumentos está vacía; esto
   significa que esta función no requiere ningun argumento. (Cuando
   veamos la definición de la función completa, veremos que se puede
   pasar un argumento opcional.)

   La expresión interactiva le indica a Emacs que se pretende utilizar la
   función de forma interactiva. En este ejemplo, @c{interactive} no tiene un
   argumento porque @c{beginning-of-buffer-simplificado} no lo requiere.

   El cuerpo de la función esta formado por dos líneas:

   ..src > elisp
     (push-mark)
     (goto-char (point-min))
   < src..

   La primera de estas líneas es la expresión, @c{(push-mark)}. Cuando el
   interprete Lisp evalua esta expresión, pone una marca en la posición actual
   del cursor, donde sea que este. La posición de esta marca se guarda en el
   anillo de marcas.

   La siguiente línea es @c{(goto-char (point-min))}. Esta expresión hace
   saltar el cursor hasta el punto mínimo en el búfer, es decir, al inicio
   del búfer (o al inicio de la porción accesible del búfer si narrowed
   esta activo. Consulta la Seccion @l{#Reducir y Extender}.)

   El comando @c{push-mark} establece una marca en el sitio donde se encontraba
   el cursor antes de que la expresión @c{(goto-char (point-min))} lo
   moviera al principio del bufer. En consecuencia, puedes, si quieres, volver a
   donde estabas originalmente presionando @k{C-x C-x}.

   ¡Esto es todo lo que hay en la definición de función!

   Cuando leas código como este y te encuentres con una función desconocida,
   como @c{goto-char}, puedes averiguar que es lo que hace mediante el
   comando @c{describe-function}. Para usar este comando, presiona @k{C-h f},
   luego escribe el nombre de la función y presiona @k{RET}. El comando
   @c{describe-function} imprimirá la cadena de documentacion de la función
   en una ventana @f{*Help*}. Por ejemplo, la documentación de @c{goto-char}
   es:

   ..example >
     Establece el punto a POSICION, un numero o marcador.
     El inicio del buffer es la posicion (point-min), el final es (point-max).
   < example..

   El argumento de la función es la posición deseada.

   (En el caso de @c{describe-function} el prompt te facilita el símbolo
   adelante o debaje del cursor, lo que te puede evitar escribir el nombre de
   la funcion al colocar el cursor encima o después de la función y luego
   presionar @k{C-h f RET}.)

   La definición de la función @c{end-of-buffer} se escribe de la misma forma
   que la definición @c{beginnig-of-buffer} excepto que el cuerpo de la
   función contiene la expresión @c{(goto-char (point-max))} en lugar de
   @c{(goto-char (point-min))}

** La definición de @c{mark-whole-buffer}

   La función @c{mark-whole-buffer} no es mas difícil de entender que la
   función @c{beginning-of-buffer-simplificado}. En este caso, sin embargo,
   veremos la función completa, no una versión reducida.

   La función @c{mark-whole-buffer} no se utiliza con tanta frecuencia como la
   función @c{beginning-of-buffer}, pero no es menos útil: marca un búfer
   completo como una región colocando el punto al inicio y una marca al final
   del búfer. Generalmente se enlaza a @k{C-x h}.

   En GNU Emacs 22, el código de la función completa se ve asi:

   ..src > elisp
     (defun mark-whole-buffer ()
       "Coloca el punto al inicio y la marca el final del buffer.
     Probablemente no deberias utilizar esta funcion en programas Lisp;
     Por lo general es un error que una funcion Lisp utilice cualquier subrutina
     que utilice o establesca la marca."
       (interactive)
       (push-mark (point))
       (push-mark (point-max) nil t)
       (goto-char (point-min)))
   < src..

   Al igual que todas las demas funciones, la función @c{mark-whole-buffer}
   encaja dentro de la plantilla de una definición de funcion. La
   plantilla luce asi:

   ..src > elisp
     (defun nombre-de-funcion (lista-de-argumentos)
       "documentacion…"
       (expresion-interactiva…)
       cuerpo…)
   < src..

   Asi es cómo funciona la función: el nombre de la función es
   @c{mark-whole-buffer}; le sigue una lista de argumentos vacía, @'c{()}, lo que
   significa que la función no requiere argumentos. La documentación viene despues.

   La siguiente línea es una expresión @c{(interactive)} que indica a Emacs
   que la función se utilizara de forma interactiva. Estos detalles son
   similares a la función @c{beginning-of-buffer-simplificado} descrita en la
   sección anterior

*** Cuerpo de @c{mark-whole-buffer}

    El cuerpo de la función @c{mark-whole-buffer} consiste en tres líneas de
    código:

    ..src > elisp
      (push-mark (point))
      (push-mark (point-max) nil t)
      (goto-char (point-min))
    < src..

    La primera de estas líneas es la expresión, @c{(push-mark (point))}.

    Esta línea hace exactamente el mismo trabajo que la primera línea del
    cuerpo de la función @c{beginning-of-buffer-simplificado}, en la que solo
    se escribe @c[(push-mark)]. En ambos casos, el intérprete Lisp coloca una
    marca en la posición actual del cursor.

    No sé por qué en la expresión @c{mark-whole-buffer} se escribe @c{(push-mark
    (point))} y en la expresión @c{beginning-of-buffer} se escribe
    @c{(push-mark)}. Quizás quien escribió el código no conocia que los
    argumentos de @c{push-mark} son opcionales y que si no se pasa un argumento
    a @c{push-mark}, la función establece automáticamente la marca en la
    posicion del punto por defecto. O quizás la expresión fué escrita de manera
    que fuera paralela a la estructura de la siguiente línea. En cualquier caso,
    la línea hace que Emacs determine la posición del punto y coloque una
    marca allí.

    En versiones anteriores de GNU Emacs, la siguiente línea de
    @c{mark-whole-buffer} era @c{(push-mark (point-max))}. Esta expresión
    establece una marca en el punto del búfer que tiene el número más alto. Este
    será el final del búfer (o, si el búfer tiene activo narrowing, el final de
    la porción accesible del búfer. Consulta la Seccion @l{#Reducir y Extender}, para
    más informacion sobre norrowing). Después de colocar esta marca, la marca
    anterior, la establecida en el punto, ya no esta establecida, pero Emacs
    recuerda su posición, al igual que todas las otras marcas recientes. Esto
    significa que, si lo deseas, puedes volver a esta posición presionando @k{C-u
    C-SPC} dos veces.

    En GNU Emacs 22, @c{(point-max)} es ligeramente más complicado. La
    línea es

    ..src > elisp
      (push-mark (point-max) nil t)
    < src..

    La expresión funciona casi igual que antes. Establece una marca en la
    posicion con el numero mas alto posible en el búfer. Sin embargo, en
    esta versión, @c{push-mark} tiene dos argumentos adicionales. El segundo
    argumento de @c{push-mark} es @c{nil}. Esto le indica a la función que debe
    @e{mostrar} un mensaje que diga ‘Mark set’ cuando se coloca la marca. El
    tercer argumento es @c{t}. Esto le indica a @c{push-mark} que active la
    marca cuando el modo Transient Mark está activo. El modo Transient Mark
    resalta la región activa. Con frecuencia esta desactivado.

    Finalmente, la última línea de la función es @c{(goto-char (point-min)))}.
    Se escribe exactamente de la misma forma como se escribio
    @c{beginning-of-buffer}. La expresión mueve el cursor al punto mínimo en el
    búfer, es decir, al inicio del búferr (o al inicio de la porción accesible
    del búfer). Como resultado de esto, el punto se coloca al inicio del búfer y la
    marca se encuentra al final del búfer. Por tanto, la región es todo el búfer.

** La definición de @c{append-to-buffer}

   El comando @c{append-to-buffer} es más complejo que el comando
   @c{mark-whole-buffer}. Lo que hace es copiar la región (es decir, la parte
   del búfer entre el punto y la marca) del buffer actual a un búfer
   específico.

   El comando @c{append-to-buffer} utiliza la función @c{insert-buffer-substring}
   para copiar la región. @c{insert-buffer-substring} se describe por su nombre:
   toma una cadena de caracteres de una parte de un búfer, una “subcadena”, y la
   inserta en otro búfer.

   La mayor parte de @c{append-to-buffer} tiene que ver con establecer las
   condiciones para que @c{insert-buffer-substring} funcione: el código debe
   especificar tanto el búfer al que ira el texto, la ventana de la que viene y
   a la que va, como la región que será copiada.

   Aquí está el texto completo de la función:

   ..src > elisp
     (defun append-to-buffer (buffer start end)
       "Añade al buffer especificado el texto de la region.
     Este se inserta en ese buffer antes de su punto.

     Cuando se llama desde un programa, se pasan tres argumentes:
     BUFFER (o nombre del buffer), START y END.
     START y END especifican la porcion del buffer actual a copiar."
       (interactive
        (list (read-buffer "Agregar al buffer: " (other-buffer
                                                 (current-buffer) t))
              (region-beginning) (region-end)))
       (let ((oldbuf (current-buffer)))
         (save-excursion
           (let* ((append-to (get-buffer-create buffer))
                  (windows (get-buffer-window-list append-to t t))
                  point)
             (set-buffer append-to)
             (setq point (point))
             (barf-if-buffer-read-only)
             (insert-buffer-substring oldbuf start end)
             (dolist (window windows)
               (when (= (window-point window) point)
                 (set-window-point window (point))))))))
   < src..

   Se puede entender la función si se mira como una serie de plantillas
   llenas.

   La plantilla exterior es para la definición de función. Esta función, se
   ve asi (con varios espacios ocupados):

   ..src > elisp
     (defun append-to-buffer (buffer start end)
       "documentacion…"
       (interactive …)
       cuerpo…)
   < src..

   La primer línea de la función incluye su nombre y tres argumentos. Los
   argumentos son el @c{buffer} al cual copiar el texto, @c{start} y @c{end}
   que son el inicio y el fin de la región del búfer actual que se
   va a copiar.

   La siguiente parte de la función es la documentación, que es clara y
   completa. Como es convencional, los tres argumentos se escriben en
   mayúsculas para que los notes con facilidad. Aun mejor, se describen en el
   mismo orden que en la lista de argumentos.

   Observa que la documentación distingue entre un búfer y su nombre. (La
   función puede manejar cualquiera.)

*** La expresión interactiva @c{append-to-buffer}

    Ya que la función @c{append-to-buffer} se puede utilizar de forma
    interactiva, la función debe tener una expresión @c{interactive}. (Para
    una analisis de @c{interactive}, consulta la seccion @l{#Crear una función
    interactiva}.)  La expresión se lee de la siguiente manera:

    ..src > elisp
      (interactive
       (list (read-buffer
              "Agregar al buffer: "
              (other-buffer (current-buffer) t))
             (region-beginning)
             (region-end)))
    < src..

    Esta expresión no tiene letras que representen partes, como se describio
    anteriormente. En su lugar, inicia una lista con estas partes:

    La primer parte de la lista es una expresión para leer el nombre de un
    búfer y devolverlo como una cadena. Es decir @c(read-buffer). La función
    requiere un prompt como primer argumento, @'{"Agregar al buffer: "}. El
    segundo argumento le indica al comando que valor proporcionar si no se
    especifica nada.

    En este caso ese segundo argumento es una expresión que contiene la
    función @c{other-buffer}, una excepción, y una @'{t}, que significa
    verdadero.

    El primer argumento de @c{other-buffer}, la excepción, es otra función,
    @c{current-buffer}. Esto no va a ser devuelto. El segundo argumento es el
    símbolo de verdadero, @c{t}. Que le dice a @c{other-buffer} que puede
    mostrar búfers visibles (excepto en este caso, que no mostrará el búfer
    actual, lo cual tiene sentido).

    La expresión se ve asi:

    ..src > elisp
      (other-buffer (current-buffer) t)
    < src..

    El segundo y tercer argumento de la expresión @c{list} son
    @c{(region-beginning)} y @c{(region-end)}. Estas dos funciones
    especifican el inicio y el final del texto a añadir.

    Originalmente, el comando utilizaba las letras @'{B} y @'{r}. Toda la
    expresión @c{interactive} se veia así:

    ..src > elisp
      (interactive "BAppend to buffer: \nr")
    < src..

    Pero cuando se hacia esto, el valor por defecto del búfer de cambió era
    invisible. Esto no era lo que se queria.

    (El prompt se separo del segundo argumento con una línea nueva,
    @'{\n}. Seguido por un @'{r} que le indica a Emacs unir los dos
    argumentos que siguen al símbolo @c{buffer} en la lista de argumentos de
    la función (es decir, @c{start} y @c{end}) a los valores del punto y
    marca. Este argumento funcionaba bien.)

*** El cuerpo de @c{append-to-buffer}

    El cuerpo de la función @c{append-to-buffer} inicia con @c{let}.

    Como hemos visto antes (Seccion @l{#@c(let)}), el propósito de una
    expresión @c{let} es crear y dar valores iniciales a una o más variables que
    solo se usaran dentro del cuerpo del @c{let}. Esto significa que esa
    variable no se confundira con ninguna variable del mismo nombre fuera
    de la expresión @c{let}.

    Podemos ver como la expresión @c{let} encaja en la función como un todo
    mostrando una plantilla de @c{append-to-buffer} con la expresión @c{let}
    en el esquema:

    ..src > elisp
      (defun append-to-buffer (buffer start end)
        "documentacion…"
        (interactive …)
        (let ((variable valor))
              cuerpo…)
    < src..

    La expresión @c{let} tiene tres elementos:

    1. El símbolo @c{let};

    2. Una varlist que contiene, en este caso, una unica lista de dos
       elementos, @c{(variable valor)};

    3. El cuerpo de la expresión @c{let}.


    En la función @c{append-to-buffer}, la varlist es la siguiente:

    ..src > elisp
      (oldbuf (current-buffer))
    < src..

    En esta parte de la expresión @c{let}, la unica variable, @c{oldbuf} se
    liga al valor devuelto por la expresión @c{(current-buffer)}. La variable,
    @c{oldbuf}, se utiliza para guardar un registro del búfer en el que se
    está trabajando y desde el que se va a copiar.

    El elemento o elementos de una varlist estan rodeados por un conjunto de
    paréntesis por lo que el intérprete Lisp puede distinguir la varlist del
    cuerpo del @c{let}. Como consecuencia, la lista de dos elementos dentro
    de la varlist está rodeada por un conjunto circunscrito de paréntesis.
    La línea tiene este aspecto:

    ..src > elisp
      (let ((oldbuf (current-buffer)))
        … )
    < src..

    Los dos paréntesis antes de @c{oldbuf} podrían sorprenderte si no fuera
    porque el primer paréntesis marca el límite de la varlist y el segundo
    paréntesis marca el inicio de la lista de dos elementos, @c{(oldbuf
    (current-buffer))}.

*** @c{save-excursion} en @c{append-to-buffer}

    El cuerpo de la expresión @c{let} dentro de @c{append-to-buffer} consiste
    en una expresión @c{save-excursion}.

    La función @c{save-excursion} guarda las posiciones de punto y marca, y
    restaura estas posiciones después de que las expresiones en el cuerpo de
    @c{save-excursion} completan su ejecución. Además, @c{save-excursion} no
    pierde de vista el búfer original, y lo restaura. Asi es como se utiliza
    @c{save-excursion} en @c{append-to-buffer}.

    Por cierto, vale la pena señalar que una función Lisp normalmente se
    formatea de modo que todo lo que esta encerrado en un conjunto de multiples
    lineas se indente más a la derecha que el primer símbolo. En esta
    definición de función, @c{let} se indenta más que @c{defun}, y
    @c{save-excursion} se indenta más que @c{let} y asi sucesivamente:

    ..src > elisp
      (defun …
        …
        …
        (let…
          (save-excursion
            …
    < src..

    Esta convención de formato hace que sea fácil ver que líneas en el
    cuerpo de @c{save-excursion} estan rodeadas por los parentesis asociados
    con @c{save-excursion}, de la misma manera que @c(save-excursion) esta
    rodeada por los paréntesis asociados con @c{let}:

    ..src > elisp
      (let ((oldbuf (current-buffer)))
        (save-excursion
          …
          (set-buffer …)
          (insert-buffer-substring oldbuf start end)
          …))
    < src..

    El uso de la función @c{save-excursion} puede verse como un proceso de
    rellenar las ranuras de una plantilla:

    ..src > elisp
      (save-excursion
        primer-expresion-en-el-cuerpo
        segunda-expresion-en-el-cuerpo
         …
        ultima-expresion-en-el-cuerpo)
    < src..

    En esta función, el cuerpo de @c{save-excursion} contiene solo una
    expresión, la expresión @c{let*}. Ya conoces la función @c{let}. La
    función @c{let*} es diferente. Posee un @'{*} en su nombre. Esto le
    permite a Emacs colocar cada variable de su varlist en secuencia, una
    después de otra.

    Su caracteristica fundamental es que las siguientes variables en la
    varlist puedan hacer uso de los valores establecidos por Emacs
    anteriormente en la varlist. Consulta la Seccion @l{#La expresión @c{let*}}.

    Vamos a omitir funciones como @c{let*} y nos centraremos en dos: la
    función @c{set-buffer} y la función @c{insert-buffer-substring}.

    En los viejos tiempos, la expresión @c{set-buffer} era simplemente:

    ..src > elisp
      (set-buffer (get-buffer-create buffer))
    < src..

    pero ahora es

    ..src > elisp
      (set-buffer append-to)
    < src..

    @c{append-to} esta ligado al @c{(get-buffer-create-buffer)} anterior en la
    expresión @c{let*}. Esta union extra no sería necesaria excepto que
    @c{append-to} se utiliza despues en la varlist como un argumento para
    @c{get-buffer-window-list}.

    La definición de la función @c{append-to-buffer} inserta texto desde el
    búfer en el que te encuentras actualmente al buffer que se indique. Sucede
    que @c{insert-buffer-substring} copia texto desde otro búfer al búfer
    actual, justo al reves––es por ello que la definición @c{append-to-buffer}
    inicia con un @c{let} que une el símbolo local @c{oldbuf} al valor devuelto
    por @c{current-buffer}.

    La expresión @c{insert-buffer-substring} es la siguiente:

    ..src > elisp
      (insert-buffer-substring oldbuf start end)
    < src..

    La función @c{insert-buffer-substring} copia una cadena @e{desde} el
    búfer especificado como su primer argumento e inserta la cadena dentro
    del búfer actual. En este caso, el argumento de @c{insert-buffer-substring}
    es el valor de la variable creada y vinculada por @c{let}, es decir, el
    valor de @c{oldbuf}, que era el búfer actual cuando se dio el comando
    @c{append-to-buffer}.

    Después de que @c{insert-buffer-substring} ha hecho su trabajo,
    @c{save-excursion} restaurará la acción al búfer original y
    @c{append-to-buffer} habrá hecho su trabajo.

    Escrito en forma esqueletal, los funcionamientos del cuerpo se ven asi:

    ..src > elisp
      (let (unir-oldbuf-al-valor-del-buffer-actual)
        (save-excursion                       ; guarda un registro del buffer.
          cambio-de-buffer
          insertar-subcadena-desde-oldbuf-a-buffer)

        regresar-al-buffer-original-al-terminar
      dejar-que-el-siginificado-local-de-oldbuf-desaparacesca-al-terminar
    < src..

    En resumen, @c{append-to-buffer} funciona de la siguiente manera: guarda el
    valor del búfer actual en la variable @c{oldbuf}. Obtiene el nuevo búfer
    (creando uno si es necesario) y cambia la atención de Emacs a este. Usando
    el valor de @c{oldbuf}, inserta la región del texto desde el búfer antiguo
    dentro del nuevo búfer; y luego usando @c{save-excursion}, regresa al búfer
    original.

    Al observar @c{append-to-buffer}, se ha explorado una función bastante
    compleja. Muestra como usar @c{let} y @c{save-excursion}, y como cambiar
    y volver desde otro buffer. Muchas definiciones de función usan @c{let},
    @c{save-excursion}, y @c{set-buffer} de esta manera.

** Repaso

   Aquí está un breve resumen de las diferentes funciones descritas en este
   capítulo.

   - @c(describe-function), @c(describe-variable) ::

     Imprimen la documentación de una función o variable. Convencionalmente
     unidas a @k{C-h f} y @k{C-h v}.

   - @c(find-tag) ::

     Encuentra el fichero que contiene el codigo de una función o variable y
     cambia a dicho buffer, colocando el punto al inicio del elemento.
     Convencionalmente ligado a @k{M-.} (esto es un punto luego de la tecla
     @k{META}).

   - @c(save-excursion) ::

     Guarda la posicion de punto y marca y restaura sus valores tras evaluar
     los argumentos de @c{save-excursion}. Ademas, recuerda el buffer actual
     y regresa a el.

   - @c(push-mark) ::

     Establece la marca a una posicion y registra el valor de la marca anterior en
     el anillo de marcas. La marca es una ubicacion en el búfer que
     mantendra su posición relativa, incluso si se añade o borra texto del
     búfer.

   - @c(goto-char) ::

     Establece el punto a la ubicacion especificada por el valor del
     argumento, que puede ser un número, una marca, o una expresión que
     devuelve el número de una posición, como @c{(point-min)}.

   - @c(insert-buffer-substring) ::

     Copia una región de texto desde un búfer que se pasa a la función como
     argumento e inserta la región dentro del búfer actual.

   - @c(mark-whole-buffer) ::

     Marca el búfer completo como una región. Normalmente unido a @k{C-x h}.

   - @c(set-buffer) ::

     Cambia la atención de Emacs a otro búfer, pero no se muestra el cambio
     en la ventana. Se utiliza cuando un programa y no un humano trabaja en un
     búfer distinto.

   - @c(get-buffer-create), @c(get-buffer) ::

     Busca un búfer con nombre o crea uno si el búfer con ese nombre no
     existe. La función @c{get-buffer} devuelve @c{nil} si el nombre del
     búfer no existe.

** Ejercicios

   - Escribe tu propia definición de la función @c{end-of-buffer-simplicifado};
     luego pruebala para ver si funciona.

   - Utiliza @c{if} y @c{get-buffer} para escribir una función que imprima un
     mensaje que indique si un buffer existe.

   - Usando @c{find-tag}, busca el codigo de la función @c{copy-to-buffer}

* Algunas Funciones Más Complejas

  En este capítulo, nos basamos en lo que hemos aprendido en los capítulos
  anteriores al analizar funciones más complejas. La función @c{copy-to-buffer}
  ilustra el uso de dos expresiones @c{save-excursion} en una definición,
  mientras que la función @c{insert-buffer} ilustra el uso de un asterisco en
  una expresión @c{interactive}, el uso de @c{or}, y la importante distinción
  entre un nombre y el objeto al que el nombre hace referencia.

** La definición de @c{copy-to-buffer}

   Después de comprender cómo trabaja @c{append-to-buffer}, es fácil entender
   @c{copy-to-buffer}. Esta función copia texto dentro de un búfer, pero en
   lugar de agregarlo al segundo búfer, sustituye todo el texto en el segundo
   búfer.

   El cuerpo de @c{copy-to-buffer} tiene este aspecto,

   ..src > elisp
     …
     (interactive "BCopy to buffer: \nr")
     (let ((oldbuf (current-buffer)))
       (with-current-buffer (get-buffer-create buffer)
         (barf-if-buffer-read-only)
         (erase-buffer)
         (save-excursion
           (insert-buffer-substring oldbuf start end)))))
   < src..

   La función @c{copy-to-buffer} tiene una expresión @c{interactive} mas
   sencilla que @c{append-to-buffer}.

   La definición dice:

   ..src > elisp
     (with-current-buffer (get-buffer-create buffer) …
   < src..

   En primer lugar, mira la expresión más interna; que se evalua primero.
   Esta expresión inicia con @c{get-buffer-create buffer}. La función le indica
   al ordenador que utilice el búfer con el nombre específicado como aquel que
   quieres copiar, o si tal búfer no existe, que lo cree. Luego, la función
   @c{with-current-buffer} evalúa su cuerpo con este búfer temporal.

   (Esto demuestra otra forma de cambiar la atención del ordenador pero no
   la del usuario. La función @c{append-to-buffer} muestro como hacer lo
   mismo con @c{save-excursion} y @c{set-buffer}. @c{with-current-buffer} es un
   mecanismo nuevo, y posiblemente mas sencillo.)

   La función @c{barf-if-buffer-read-only} envía un mensaje de error diciendo
   que el búfer es de solo lectura si no se puede modificar.

   La siguiente línea tiene como único contenido la función
   @c{erase-buffer}. Este función borra el búfer.

   Finalmente, las últimas dos líneas contienen la expresión @c{save-excursion}
   con @c{insert-buffer-substring} como cuerpo. La expresión
   @c{insert-buffer-substring} copia el texto desde el búfer en el que te
   encuentras (y no has visto al ordenador cambiar su atención, por lo que no
   sabes que ese búfer ahora se llama @c{oldbuf}).

   Por cierto, esto es lo que se entiende por ‘reemplazo’. Para reemplazar el
   texto Emacs borra el texto anterior y luego inserta un texto nuevo.

   A grandes rasgos, el cuerpo de @c{copy-to-buffer} se ve asi:

   ..src > elisp
     (let (enlazar-oldbuf-al-valor-del-bufer-actual)
         (con-el-bufer-al-que-estas-copiando
           (pero-no-borrar-o-copiar-a-un-bufer-de-solo-lectura)
           (erase-buffer)
           (save-excursion
             insertar-la-subcadena-desde-oldbuf-en-el-bufer)))
   < src..

** La definición de @c{insert-buffer}

   @c{insert-buffer} es otra función relacionada con búfers. Este comando copia
   otro búfer @e{dentro} del búfer actual. Es lo contrario a @c{append-to-buffer}
   o @c{copy-to-buffer}, dado que copia una región de texto @e{desde} el búfer
   actual a otro búfer.

   Aquí examinamos en el código original. El código se simplifico en 2003 y
   es mas dificil de entender.

   (Consulta la Seccion @l{#Nuevo Cuerpo para @c{insert-buffer}}, para ver una
   discusión del nuevo cuerpo.)

   Además, este código ilustra el uso de @c{interactive} con un búfer que
   podría ser @:{read-only} @%i(de solo lectura) y la importante distinción entre
   el nombre de un objeto y el objeto al que realmente hace referencia.

   Aquí está el código anterior:

   ..src > elisp
     (defun insert-buffer (buffer)
       "Insertar despues del punto el contenido de BUFFER.
     Coloca la marca despues del texto insertado.
     BUFFER puede ser un buffer o el nombre de un buffer."
       (interactive "*bInsert buffer: ")
       (or (bufferp buffer)
           (setq buffer (get-buffer buffer)))
       (let (start end newmark)
         (save-excursion
           (save-excursion
             (set-buffer buffer)
             (setq start (point-min) end (point-max)))
           (insert-buffer-substring buffer start end)
           (setq newmark (point)))
         (push-mark newmark)))
   < src..

   Al igual que con otras definiciones de función, se puede usar una plantilla
   para ver un esquema de la función:

   ..src > elisp
     (defun insert-buffer (buffer)
       "documentacion…"
       (interactive "*bInsert buffer: ")
       cuerpo…)
   < src..

*** La expresión interactiva en @c{insert-buffer}

    En @c{insert-buffer}, el argumento de la declaración @c{interactive} tiene
    dos partes, un asterisco, @'c{*}, y @'c{bInsert buffer: }.

**** Un búfer de solo lectura

     El asterisco se utliza cuando el búfer actual es un búfer de solo
     lectura––un búfer que no se puede modificar. Si se llama a
     @c{insert-buffer} cuando el búfer actual es de solo lectura, se imprime un
     mensaje en el area de eco y el terminal puede emitir un beep o parpadear;
     no se permitira insertar nada en el búfer actual. El asterisco no tiene que
     ser seguido por un salto de linea para separarlo del siguiente argumento.

**** @'c{b} en una expresión interactiva

     El siguiente argumento de la expresión interactiva inicia con una letra
     @'c{b} minúscula. (Esto es diferente del código para @c{append-to-buffer},
     que utiliza una @'c{B} mayúscula. Consulta la Seccion @l{#La Definición de
     @c{append-to-buffer}}.) La @'c{b} minúscula le indica al intérprete Lisp que
     el argumento de @c{insert-buffer} debe ser un buffer existente o su
     nombre. (La opcion @'c{B} mayúscula permite la posibilidad de que el búfer no
     exista.) Emacs te pedira el nombre del búfer, ofreciendo un búfer por
     defecto, con el autocompletado de nombre habilitado. Si el búfer no existe,
     recibiras un mensaje que dice “No match” @%i"(no concuerda); tu terminal
     tambien puede emitir un beep.

     El nuevo código simplificado genera una lista para @c{interactive}. Este
     utiliza las funciones @c{barf-if-buffer-read-only} y @c{read-buffer} con
     las que ya estamos familiarizados y la forma especial @c{progn} con la que
     no lo estamos. (Se describira mas adelante).

*** El cuerpo de la función @c{insert-buffer}

    El cuerpo de la función @c{insert-buffer} tiene dos partes principales: una
    expresión @c{or} y una expresión @c{let}. El propósito de la expresión
    @c{or} es asegurar que el argumento @c{buffer} esta ligado a un búfer y no
    solo al nombre de un búfer. El cuerpo de la expresión @c{let} contiene
    el código que copia el otro búfer dentro del búfer actual.

    A grades rasgos, las dos expresiones encajan asi en la función @c{insert-buffer}:

    ..src > elisp
      (defun insert-buffer (buffer)
        "documentacion…"
        (interactive "*bInsert buffer: ")
        (or …
            …
        (let (varlist)
            cuerpo-de-let… )
    < src..

    Para entender como la expresión @c{or} asegura que el argumento @c{buffer}
    esta unido a un búfer y no al nombre de un búfer, primero es necesario
    entender la función @c{or}.

    Antes de hacer esto, permíteme reescribir esta parte de la función
    utilizando @c{if} de esta manera puedes ver como se hace de una manera que
    resulte familiar.

*** @c{insert-buffer} con un @c{if} en lugar de un @c{or}

    El trabajo a realizar es asegurarse de que el valor de @c{buffer} sea un
    búfer en sí mismo y no el nombre de un búfer. Si el valor es el nombre, entonces
    debe optenerse el búfer en sí.

    Puedes imaginarte a tí mismo en una conferencia donde un acomodador está
    observando una lista con tu nombre en ella y mirándote: el acomodador sabe
    “asociar” tu nombre, no a tí; pero cuando el acomodador te encuentra y
    te toma el brazo, el acomodador lo “asocia” a tí.

    En Lisp, se podría describir esta situación así:

    ..src > elisp
      (if (not (tomar-al-invitado))
          (encontrar-y-tomar-del-brazo-al-invitado))
    < src..

    Queremos hacer lo mismo con un búfer––si no tenemos el búfer en sí,
    queremos conseguirlo.

    Usando un predicado llamado @c{bufferp} que nos informa si tenemos un búfer
    (en lugar de su nombre), podemos escribir el código de esta manera:

    ..src > elisp
      (if (not (bufferp buffer))              ; parte-if
          (setq buffer (get-buffer buffer)))  ; parte-then
    < src..

    Aquí, la prueba verdadero-o-falso de la expresión @c{if} es @c{(not (bufferp
    buffer))}; y la parte @e(then) es la expresión @c{(setq buffer (get-buffer
    buffer))}.

    En la prueba, la función @c{bufferp} devuelve verdadero si su argumento es un
    búfer––sino falso si el argumento es el nombre del búfer. (El último
    carácter del nombre de la función @c{bufferp} es el carácter @'c{p}; como
    vimos anteriormente, tal uso de @'c{p} es una convención que indica que la
    función es un predicado, que es un término que significa que la función
    determinará si alguna propiedad es verdadera o falsa. Consulta la Seccion
    @l(#Usando el tipo incorrecto de objeto como argumento).)

    La función @c{not} precede a la expresión @c{(bufferp buffer)}, así la prueba
    verdadero-o-falso es la siguente:

    ..src > elisp
      (not (bufferp buffer))
    < src..

    @c{not} es una función que devuelve verdadero si su argumento es falso y
    falso si su argumento es verdadero. Por lo que si @c{(bufferp buffer)}
    devuelve verdadero, la expresión @c{not} devuelve falso y viceversa: lo que es
    “no verdadero” es falso y lo que es “no falso” es verdadero.

    Usando esta prueba, la expresión @c{if} funciona de la siguiente manera:
    cuando el valor de la variable @c{buffer} es realmente un búfer en
    lugar de su nombre, la prueba verdadero-o-falso devuelve falso y la
    expresión @c{if} no evalúa la parte-then. Esto está bien, ya que no tenemos
    que hacer nada para la variable @c{buffer} si realmente es un búfer.

    Por otro lado, cuando el valor de @c{buffer} no es un buffer en sí, pero si
    el nombre de un buffer, la prueba verdadero-o-falso devuelve verdadero y se
    evalua la parte-then de la expresión. En este caso, la parte-then es
    @c{(setq buffer (get-buffer buffer))}. Esta expresión utiliza la función
    @c{get-buffer} para devolver un buffer real, dado su nombre. Luego @c{setq}
    asigna la variable @c{buffer} reemplazando su valor anterior (que era el
    nombre del búfer).

*** El @c{or} en el cuerpo

    El propósito de la expresión @c{or} en la función @c{insert-buffer} es
    asegurar que el argumento @c{buffer} está ligado a un búfer y no solo al
    nombre de uno. La sección previa muestra como se podría haber hecho el
    trabajo usando una expresión @c{if}. Sin embargo, la función
    @c{insert-buffer} utiliza @c{or}. Para entender esto, es necesario entender
    como funciona @c{or}.

    Una función @c{or} puede tener cualquier número de argumentos. Evalúa
    un argumento a la ves y devuelve el valor del primero de sus argumentos que
    no es @c{nil}. Ademas, y esta es una caracteristica crucial de @c{or}, no
    evalúa ningun argumento posterior después de regresar el primer valor
    no-@c{nil}.

    La expresión @c{or} se ve asi:

    ..src > elisp
      (or (bufferp buffer)
          (setq buffer (get-buffer buffer)))
    < src..

    El primer argumento de @c{or} es la expresión @c{(bufferp buffer)}. Esta
    expresión devuelve verdadero (un valor no-@c{nil}) si el búfer es realmente
    un búfer, y no solo el nombre de un búfer. En la expresión @c{or}, si este
    es el caso, la expresión @c{or} devuelve este valor verdadero y no evalúa la
    siguiente expresión––y esto esta bien para nosotros, ya que no queremos hacer
    nada con el valor de @c{buffer} si realmente es un búfer.

    Por otro lado, si el valor de @c{(bufferp buffer)} es @c{nil}, que lo sera
    si el valor de @c{buffer} es el nombre de un buffer, el intérprete Lisp
    evalúa el siguiente elemento de la expresión. Esta es la expresión @c{(setq
    buffer (get-buffer buffer))}. Esta expresión devuelve un valor no-@c{nil},
    que es el valor al que establece la variable @c{buffer}––y este valor es
    un búfer en sí, no el nombre de un búfer.

    El resultado de todo esto es que el símbolo @c{buffer} siempre esta ligado a
    un búfer en sí mismo y no al nombre de uno. Todo esto es necesario
    porque la función @c{set-buffer} en la línea siguiente solo funciona
    con un buffer en sí, no con el nombre de un búfer.

    A proposito, usando @c{or}, la escena con el acomodador se escribiria así:

    ..src > elisp
      (or (tomar-al-invitado) (encontrar-y-tomar-del-brazo-al-invitado))
    < src..

*** La expresión @c{let} en @c{insert-buffer}

    Después de asegurarse que la variable @c{buffer} se refiere a un buffer en
    sí y no solo al nombre de uno, la función @c{insert-buffer} continúa
    con una expresión @c{let}. Esta especifica tres variables locales,
    @c{start}, @c{end} y @c{newmark} y las une al valor inicial @c{nil}. Estas
    variables se utilizan dentro del resto de @c{let} y ocultan temporalmente
    cualquier otra ocurrencia de variables con el mismo nombre en Emacs hasta el
    final de @c{let}.

    El cuerpo de @c{let} contiene dos expresiones @c{save-excursion}. Primero,
    veremos la expresión interna @c{save-excursion} en detalle. La expresión
    se ve asi:

    ..src > elisp
      (save-excursion
        (set-buffer buffer)
        (setq start (point-min) end (point-max)))
    < src..

    La expresión @c{(set-buffer buffer)} cambia la atención de Emacs del
    búfer actual al buffer desde donde se copiara el texto. En ese búfer las
    variables @c{start} y @c{end} se asignan al inicio y al fin del búfer,
    usando los comandos @c{point-min} y @c{point-max}. Observa que
    tenemos aquí un ejemplo de cómo @c{setq} es capaz de asignar dos variables
    en la misma expresión. El primer argumento de @c{setq} se establece al valor
    del segundo, y el tercer argumento se establece al valor del cuarto.

    Después de evaluar el interior del cuerpo de @c{save-excursion},
    @c{save-excursion} restaura el búfer original, pero @c{start} y @c{end}
    retienen los valores del inicio y fin del búfer del que se copiara el texto.

    La expresión extena de @c{save-excursion} luce asi:

    ..src > elisp
      (save-excursion
        (expresion-interior-de-save-excursion
           (ir-al-nuevo-bufer-y-establecer-start-y-end)
        (insert-buffer-substring buffer start end)
        (setq newmark (point)))
    < src..

    La función @c{insert-buffer-substring} copia el texto @e{dento} del búfer
    actual @e{desde} la región indicada por @c{start} y @c{end} en el
    @c{buffer}. Puesto que la totalidad del segundo búfer se encuentra entre
    @c{start} y @c{end}, todo dentro del segundo búfer se copia el bufer que
    se esta editando. A continuacion, el valor del punto, que estara al final del
    texto insertado, se registra en la variable @c{newmark}.

    Después de evaluar el cuerpo del @c{save-excursion} externo, el punto y la
    marca se vuelven a colocar en su posicion original.

    Sin embargo, es conveniente ubicar una marca al fin del texto recien
    insertado y ubicar el punto al principio. La variable @c{newmark} registra
    el fin del texto insertado. En la última línea de la expresión @c{let}, la
    expresión @c{(push-mark newmark)} asigna una marca a esta posición. (La
    posición anterior de la marca aun es accesible; se registra en el anillo de
    marcas y puedes volver a ella con @k{C-u C-SPC}.) Mientras tanto, el punto
    se encuentra al principio del texto insertado, que es donde estaba antes de
    llamar a la función de insercion, cuya posición fue guardada por la primer
    @c{save-excursion}.

    La expresión @c{let} completa se ve asi:

    ..src > elisp
      (let (start end newmark)
        (save-excursion
          (save-excursion
            (set-buffer buffer)
            (setq start (point-min) end (point-max)))
          (insert-buffer-substring buffer start end)
          (setq newmark (point)))
        (push-mark newmark))
    < src..

    Al igual que la función @c{append-to-buffer}, la función @c{insert-buffer}
    utiliza @c{let}, @c{save-excursion} y @c{set-buffer}. Además, la función
    ilustra una forma de utilizar @c{or}. Todas estas funciones son bloques de
    construccion que vamos a encontrar y utilizar una y otra vez.

*** Nuevo cuerpo para @c{insert-buffer}

    El cuerpo en la versión 22 de GNU Emacs es más confuso que el original.

    Se compone de dos expresiones

    ..src > elisp
      (push-mark
       (save-excursion
         (insert-buffer-substring (get-buffer buffer))
         (point)))

      nil
    < src..

    excepto que, y esto es lo que confunde a los novatos, se hace un
    trabajo muy importante al interior de la expresión @c{push-mark}.

    La función @c{get-buffer} devuelve un búfer con el nombre proporcionado.
    Notaras que la función @e{no} se llama @c{get-buffer-create}; no crea
    un búfer si no existe ya. El búfer devuelto por @c{get-buffer}, un
    búfer existente, se pasa a @c{insert-buffer-substring}, que inserta todo el
    búfer (ya que no se especifica ninguna cosa más).

    La posición en la que se inserta el buffer se registra por @c{push-mark}.
    Despues la función devuelve @c{nil}, el valor de su último comando. Dicho de
    otra manera, la función @c{insert-buffer} existe solo para producir un
    efecto secundario, insertando otro buffer, no para devolver ningun valor.

** Definición completa de @c{beginning-of-buffer}

   Ya se ha discutido la estructura básica de la función @c{beginning-of-buffer}.
   (Consulta la Seccion @l{#Una definición simplificada de @c{beginning-of-buffer}}).
   Esta sección describe la parte compleja de la definición.

   Como se ha descrito anteriormente, cuando se invoca a @c{beginning-of-buffer}
   sin argumento, mueve el cursor al inicio del búfer (en realidad, al inicio
   de la porción accesible del búfer), dejando la marca en la posición
   anterior. Sin embargo, cuando el comando se invoca con un número entre uno y
   diez, la función considera que ese número es una fracción del tamaño del búfer,
   medido en decimas, y Emacs mueve el cursor a dicha fracción del reccorrido
   desde el inicio del búfer. Por lo tanto, puedes llamar a esta función con el
   comando de teclado @k{M-<}, que moverá el cursor al principio del búfer, o
   con un comando de teclado como @k{C-u 7 M-<} que moverá el cursor a un 70%
   del recorrido a través del búfer. Si se utiliza un número mayor a diez como
   argumento, se movera al final del búfer.

   La función @c{beginning-of-buffer} puede llamarse con o sin argumentos. El
   uso del argumento es opcional.

*** Argumentos opcionales

    A menos que se diga lo contrario, Lisp espera que una función con un
    argumento en su definición de función se llamada con un valor para ese
    argumento. Si esto no ocurre, se obtiene un error y un mensaje que dice
    @'{Wrong number of arguments} @%i"(Número de argumentos erróneo).

    Sin embargo, los argumentos opcionales son una caracteristica de Lisp: se
    utiliza una @:{palabra clave} particular para decirle al intérprete Lisp
    que un argumento es opcional. La palabra clave es @c{&optional}. (El @'c{&}
    al frente de @'c{optional} es parte de la palabra clave.) En una definición
    de función, si un argumento va despues de la palabra clave @c{&optional}, no
    es necesario pasar ningún valor a ese argumento al llamar a la función.

    Por lo tanto la primera línea de la definición de función de
    @c{beginning-of-buffer} tiene este aspecto:

    ..src > elisp
      (defun beginning-of-buffer (&optional arg)
    < src..

    En lineas generales, toda la función luce asi:

    ..src > elisp
      (defun beginning-of-buffer (&optional arg)
        "documentacion…"
        (interactive "P")
        (or (es-el-argumento-una-cons-cell argumento)
            (and ambos-transient-mark-mode-y-mark-active-son-verdadero)
            (push-mark))
        (let (determina-el-tamano-y-lo-establece)
        (goto-char
          (si-hay-un-argumento
              averigua-donde-ir
            de-otro-modo-va-a
            (point-min))))
         do-nicety
    < src..

    La función es similar a la función @c{beginning-of-buffer-simplificado}
    excepto que la expresión @c{interactive} tiene @c{"P"} como argumento y la
    función @c{goto-char} es seguida por una expresión if-then-else que
    calcula donde poner el cursor si hay un argumento que no es un cons cell.

    (Puesto que no explico que es un @e(cons cell) en muchos capítulos, por
    favor, considera ignorar la función @c{consp}. Consulta la Seccion @l{#Cómo se
    implementan las listas}, y la Seccion @"l{elisp.html#Cons Cell Type<>Cons
    Cell y Tipos de Listas} en @e(El Manual de Referencia GNU Emacs Lisp)).

    La @c{"P"} en la expresión @c{interactive} le indica a Emacs que pase un
    argumento prefijo, si lo hay, en su forma @"(plana) sin procesar. Un
    argumento prefijo se crea presionando la tecla @k{META} seguida por un
    número, o pulsando @k{C-u} y luego un número. (Si no escribes un número,
    @k{C-u} por defecto pasa un cons cell con un 4. Una @c{"p"} minúscula en la
    expresión @c{interactive} hace que la función convierta un argumento prefijo
    a un número.)

    La prueba verdadero-o-falso de la expresión @c{if} parece compleja, pero no
    lo es: comprueba si @c{arg} tiene un valor que no es @c{nil} y si
    es un cons cell. (Esto es lo que hace @c{consp}; comprueba si su argumento
    es un cons cell.) Si @c{arg} tiene un valor distinto a @c{nil} (y no
    es un cons cell), que será el caso si @c{beginning-of-buffer} se llama con
    un argumento numerico, la prueba verdadero-o-falso devolverá verdadero y se
    evaluara la parte-then de la expresión @c{if}. Por otro lado, si
    @c{beginning-of-bufer} no se llama con un argumento, el valor de
    @c{arg} será @c{nil} y se evaluara la parte-else de la expresión
    @c{if}. La parte-else es simplemente @c{point-min}, y cuando este es el
    resultado, toda la expresión @c{goto-char} es @c{(goto-char (point-min))},
    que es cómo vimos la función @c{beginning-of-buffer} en su forma
    simplificada.

*** @c{beginning-of-buffer} con un argumento

    Cuando se llama a @c{beginning-of-buffer} con un argumento, se evalua una
    expresión que calcula que valor pasar a @c{goto-char}. A primera vista esta
    expresion es bastante compleja. Incluye una expresión @c{if} y mucha
    aritmética. Se ve así:

    ..src > elisp
      (if (> (buffer-size) 10000)
          ;; Evita el desbordamiento en buffers de gran tamaño!
          (* (prefix-numeric-value arg)
             (/ size 10))
        (/ (+ 10
              (* size (prefix-numeric-value arg)))
           10))
    < src..

    Como otras expresiones que parecen complejas, la expresión condicional
    dentro de @c{beginning-of-buffer} se puede desenredar viendola como partes
    de una plantilla, en este caso, con la plantilla para una expresión
    if-then-else. En forma esquelética, la expresión se ve así:

    ..src > elisp
      (if (buffer-es-grande
          divide-el-tamaño-del-buffer-por-10-y-multiplicalo-por-arg
        de-otra-forma-utiliza-el-calculo-alternativo
    < src..

    La prueba verdadero-o-falso de la expresión @c{if} interna comprueba el
    tamaño del buffer. La razón de esto es que la vieja versión de Emacs 18
    utilizaba números que no superaban los ocho millones y en el siguiente
    calculo, el programador temía que Emacs pudiera intentar usar numeros
    demasiado grandes si el búfer era extenso. El término ‘desbordamiento’,
    que se menciona en el comentario, significa que los números son demaciado
    grandes. Las versiones más recientes de Emacs utilizan números mas grandes,
    pero este código no ha sido tocado, aunque solo sea porque la gente ahora
    mira búfers que son mucho, mucho mas grandes que antes.

    Hay dos casos: si el búfer es grande, o si no lo es.

**** Qué ocurre en un búfer de gran tamaño

     En @c{beginning-of-buffer}, la expresión @c{if} interna prueba si el tamaño
     del búfer es mayor a 10000 caracteres. Para ello, se utiliza la
     función @c{>} y el calculo de @c{size} que proviene de la expresión @c(let).

     En los viejos tiempos, se utilizaba la función @c{buffer-size}. No solo se
     llamo varias ocaciones esa funcion, sino que dio el tamaño de todo el
     búfer, no la parte accesible. El calculo tiene mucho más sentido cuando se
     maneja solo la parte accesible. (Consulta la Seccion @l{#Reducir y Extender},
     para obtener más información sobre como centrar la atención en una parte
     ‘accesible’.)

     La linea se ve asi:

     ..src > elisp
       (if (> size 10000)
     < src..

     Cuando el búfer es grande, se evalua la parte-then de la expresión
     @c{if}. Se lee así (después de formatearlo para facilitar la lectura):

     ..src > elisp
       (*
         (prefix-numeric-value arg)
         (/ size 10))
     < src..

     Esta expresión es una multiplicación, con dos argumentos para la función
     @c{*}.

     El primer argumento es @c{(prefix-numeric-value arg)}. Cuando se usa
     @c{"P"} como argumento para @c{interactive}, el valor pasado a la función
     como argumento es un “argumento prefijo en bruto”, y no un número. (Es un
     número en una lista). Para realizar el calculo, se necesita una conversión,
     y @c{prefix-numeric-value} hace el trabajo.

     El segundo argumento es @c{(/ size 10)}. Esta expresión divide el valor
     numérico por diez––el valor numérico del tamaño de la porción accesible del
     búfer. Esto produce un número que indica cuántos caracteres componen
     una decima parte del tamaño del búfer. (En Lisp, @c{/} se utiliza para la
     división, igual que @c{*} se utiliza para la multiplicación.)

     En la expresión de multiplicación como un todo, esta cantidad se
     multiplica por el valor del argumento prefijo––la multiplicación es la
     siguiente:

     ..src > elisp
       (* valor-numerico-del-argumento-prefijo-arg
          numero-de-caracteres-en-una-decima-parte-de-la-porcion-accesible-del-buffer)
     < src..

     Si, por ejemplo, el argumento prefijo es @'{7}, el valor de una decima parte
     será multiplicado por 7 para dar una posición del 70% del trayecto.

     El resultado de todo esto es que si la porción accesible del búfer es
     grande, la expresión @c{goto-char} es la siguiente:

     ..src > elisp
       (goto-char (* (prefix-numeric-value arg)
                     (/ size 10)))
     < src..

     Esto coloca el cursor donde lo queremos.

**** Lo que sucede en un búfer pequeño

     Si el búfer contiene menos de 10,000 caracteres, se lleva a cabo un calculo
     ligeramente diferente. Podrías pensar que esto no es necesario, ya que el
     primer calculo podría hacer el trabajo. Sin embargo, en un búfer pequeño,
     el primer método puede no colocar el cursor exactamente en la línea
     deseada; el segundo método hace un mejor trabajo.

     El código es el siguiente:

     ..src > elisp
       (/ (+ 10 (* size (prefix-numeric-value arg))) 10))
     < src..

     Para averiguar que ocure en este código debemos descubrir como se anidan
     las funciones entre paréntesis. Es mas fácil de leer si se reformatea cada
     expresión, indentando la expresión que contiene:

     ..src > elisp
         (/
          (+ 10
             (*
              size
              (prefix-numeric-value arg)))
          10))
     < src..

     Observando los paréntesis, vemos que la operación mas profunda es
     @c{(prefix-numeric-value arg)}, que convierte el argumento prefijo en bruto
     a un número. En la siguiente expresión, este número se multiplica por el
     tamaño de la porción accesible del búfer:

     ..src > elisp
       (* size (prefix-numeric-value arg))
     < src..

     Esta multiplicación crea un número que puede ser mayor al tamaño del
     buffer––siete veces mayor si el argumento es 7, por ejemplo. Luego se suma
     diez a éste numero y finalmente el número se divide por 10 para
     proporcionar un valor que es un carácter más grande que la posición
     porcentual en el búfer.

     El número que resulta de todo esto se pasa a @c{goto-char} y el cursor
     se mueve a ese punto.

*** Funcion @c{beginning-of-buffer} Completa

    Aquí está el texto completo de la función @c{beginning-of-buffer}:

    ..src > elisp
      (defun beginning-of-buffer (&optional arg)
        "Mueve el punto al principio del bufer;
      deja la marca en la posicion anterior.
      Con el prefijo \\[universal-argument],
      no establece la marca en la posicion anterior.
      Con un argumento numerico N,
      coloca el punto N/10 del camino desde el inicio.

      Si el bufer tiene activo narrowing,
      este comando utiliza el principio y el tamaño
      de la parte accesible del bufer.

      No utilice este comando en programas Lisp!
      \(goto-char (point-min)) es mas rapido y evita
      tocar la marca."
        (interactive "P")
        (or (consp arg)
            (and transient-mark-mode mark-active)
            (push-mark))
        (let ((size (- (point-max) (point-min))))
          (goto-char (if (and arg (not (consp arg)))
                         (+ (point-min)
                            (if (> size 10000)
                                ;; Evita el desbordamiento en los búfers de gran tamaño!
                                (* (prefix-numeric-value arg)
                                   (/ size 10))
                              (/ (+ 10 (* size (prefix-numeric-value arg)))
                                 10)))
                       (point-min))))
        (if arg (forward-line 1)))
    < src..

    Excepto por dos pequeños puntos, la discusión anterior muestra cómo funciona
    esta función. El primer punto se refiere a un detalle en la cadena de
    documentación, y el segundo se refiere a la última línea de la función.

    En la cadena de documentación, hay una referencia a una expresión:

    ..example >
      \\[universal-argument]
    < example..

    Se usa Un @'{\\} antes del primer corchete de esta expresión. Este @'{\\} le
    indica al intérprete Lisp que sustituya cualquier clave qué se encuentre
    dentro de @'{[…]} por su convinacion de teclado actual. En el caso de
    @c{universal-argument}, suele ser @k{C-u}, pero podría ser distinta. (Consulta la
    Sección @l{elisp.html#Documentation Tips<>Consejos para Cadenas de
    Documentación} en @e(El Manual de Referencia de GNU Emacs Lisp), para más
    información.)

    Finalmente, la última línea del comando @c{beginning-of-buffer} dice que hay
    que mover el punto al inicio de la siguiente línea si el comando se invoca
    con un argumento:

    ..src > elisp
      (if arg (forward-line 1)))
    < src..

    Esto coloca el cursor al inicio de la primer línea despues de la posicion
    inidicada en decimas en el búfer. Esto significa que el cursor siempre se
    localiza @e{al menos} las decimas del recorrido solicitadas del búfer, esta
    es una sutiliza, quizás, no necesaria, pero que, si no ocurriera, seguro
    suscitaria quejas.

    Por otro lado, tambien significa que si se especifica el comando con @k{C-u},
    pero sin un número, es decir, si el ‘argumento prefijo en bruto’ simplemente
    es un cons cell, entonces el comando te coloca al inicio de la segunda línea
    … no sé si se pretende esto o si nadie ha tratado el código para evitar que
    esto suceda.

** Repaso: Algunas Funciones Más Complejas <> Repaso

   He aquí un breve resumen de algunos de los temas cubiertos en este capítulo.

   - @c(or) ::

     Evalúa cada argumento en secuencia, y devuelve el valor del primer
     argumento que no es @c{nil}, si ninguno devuelve un valor que no sea
     @c{nil}, devuelve @c{nil}. En resumen, devuelve el primer valor verdadero
     de los argumento; devuelve un valor verdadero si uno @e{o} cualquiera de
     los otros es verdadero.

   - @c(and) ::

     Evalúa cada argumento en secuencia, y si alguno es @c{nil}, devuelve
     @c{nil}; si ninguno es @c{nil}, devuelve el valor del último argumento. En
     resumen, devuelve un valor verdadero solo si todos los argumentos son
     verdaderos; devuelve un valor verdadero si uno @e{y} cada uno de los otros
     son verdadero.

   - @c(&optional) ::

     Una palabra clave utilizada para indicar que un argumento en una definición
     de función es opcional; esto significa que la función se puede evaluar sin
     el argumento, si se desea.

   - @c(prefix-numeric-value) ::

     Convierte el ‘argumento prefijo en bruto’ producido por @c{(interactive
     "P")} en un valor numérico.

   - @c(forward-line) ::

     Mueve el punto hacia adelante al principio de la siguiente línea, o si el
     argumento es mayor a uno, hacia delante varias líneas. Si no puede avanzar
     tanto hacia delante como se supone, @c{forward-line} va hacia adelante
     tan lejos como pueda y luego devuelve un conteo del número de líneas
     adicionales que debia avanzar poro no pudo.

   - @c(erase-buffer) ::

     Elimina todo el contenido del búfer actual.

   - @c(bufferp) ::

     Devuelve @c{t} si su argumento es un búfer; de otro modo devuelve
     @c{nil}.

** Ejercicio con el argumento @c{opcional}

   Escribe una función interactiva con un argumento opcional que comprueve si su
   argumento, un número, es mayor o igual o menor que el valor de
   @c{fill-column}, y lo informe, en un mensaje. Sin embargo, si no se pasa un
   argumento a la función, utiliza 56 como valor por defecto.

* Reducir y Extender

  La reduccion @%i(narrowing) es una funcionalidad de Emacs que hace posible que
  puedas focalizarte en una parte específica de un búfer, y trabajar sin cambiar
  accidentalmente otras partes. La reduccion normalmente se deshabilita ya que
  puede confundir a los principiantes.

  Con la reduccion, el resto del búfer se hace invisible, como si no estuviera
  alli. Esto es una ventaja si, por ejemplo, se quiere reemplazar una palabra en
  una parte del búfer pero no en otra: limitas la parte que deseas y el
  reemplazo se lleva a cabo solo en esa sección, no en el resto del búfer. Las
  búsquedas solo funcionarán con la región reducida, no fuera de ella, de esta
  forma si estás reparando una parte de un documento, puedes mantener fuera la
  parte que no necesitas. (El atajo asociado a @c{narrow-to-region} es @k{C-x n n}.)

  Sin embargo, la reduccion hace invisible el resto del búfer, lo que puede
  asustar a quien invoca inadvertidamente la reduccion y piensa que ha eliminado
  una parte de su fichero. Ademas, el comando @c{undo} (usualmente ligado
  a @k{C-x u}) no desactiva la reduccion (ni debe hacerlo), por lo que las personas
  pueden llegar a desesperarse si no saben que pueden devolver el resto del
  buffer a la visibilidad cor el comando @c{widen} que es @k{C-x n w}.)

  La reduccion es igual de util para el intérprete Lisp como para un humano.
  Con frecuencia, una función Emacs Lisp está diseñada para trabajar solo en
  parte de un búfer; o por el contrario, una función Emacs Lisp necesita
  trabajar en todo un búfer que ha sido reducido. La función @c{what-line}, por
  ejemplo, elimina la reduccion de un búfer, si este tiene alguna reduccion y
  al terminar su trabajo, restaura la reduccion. Por otro lado, la función
  @c{count-lines} utiliza la reduccion para restringirse a sí misma solo a la
  porción del búfer en la que se está interesado y luego restaura la situación
  anterior.

** La forma especial @c{save-restriction}

   En Emacs Lisp, se puede utilizar la forma especial @c{save-restriction} para
   llevar un registro de cualquier reduccion en efecto. Cuando el intérprete
   Lisp se encuentra con @c{save-restriction}, ejecuta el código en el cuerpo
   de la expresión @c{save-restriction}, y luego deshace cualquier cambio en la
   reduccion causada por el código. Si, por ejemplo, el búfer es reducido y el
   código que sigue al comando @c{save-restriction} se deshace de la reduccion,
   @c{save-restriction} devuelve el búfer a su región reducida.  En el comando
   @c{what-line}, cualquier reduccion del búfer puede anularse por el comando
   @c{widen} inmediatamente despues del comando @c{save-restriction}. Se
   restaura cualquier reduccion original justo antes de finalizar la función.

   La plantilla para una expresión @c{save-restriction} es simple:

   ..src > elisp
     (save-restriction
       cuerpo… )
   < src..

   El cuerpo de @c{save-restriction} es una o más expresiones que seran evaluadas
   de forma secuencial por el intérprete Lisp.

   Finalmente, un punto a tener en cuenta: cuando utilices @c{save-excursion}
   y @c{save-restriction} a la vez, una detras de la otra, debes utilizar
   @c{save-excursion} primero. Si lo escribes en orden inverso, es posible
   que no registre la reduccion en el búfer al que emacs debe cambiar Emacs
   despues de llamar a @c{save-excursion}. Por lo tanto, cuando escribas a la
   vez @c{save-excursion} y @c{save-restriction} debe ser así:

   ..src > elisp
     (save-excursion
       (save-restriction
         cuerpo…))
   < src..

   En otras circunstancias, cuando no se escriban a la vez, las formas
   especiales @c{save-excursion} y @c{save-restriction} deben escribirse en el
   orden adecuado para la función.

   Por ejemplo,

   ..src > elisp
     (save-restriction
       (widen)
       (save-excursion
       cuerpo…))
   < src..

** @c{what-line}

   El comando @c{what-line} informa el número de la línea en la que el cursor
   esta colocado. La función ilustra el uso de los comandos @c{save-restriction}
   y @c{save-excursion}. Aquí está el texto original de la función:

   ..src > elisp
     (defun what-line ()
       "Imprime el numero de linea actual (en el bufer) del punto."
       (interactive)
       (save-restriction
         (widen)
         (save-excursion
           (beginning-of-line)
           (message "Line %d"
                    (1+ (count-lines 1 (point)))))))
   < src..

   (En versiones recientes de GNU Emacs, la función @c{what-line} se ha ampliado
   para decirte el numero de linea en un búfer reducido, asi como el número
   de línea en un búfer extendido. La versión reciente es más compleja que la
   versión que se muestra aqui. Si te sientes aventurero, puede que quieras
   verla despues de averiguar como funciona esta version. Probablemente
   necesites utilizar @k{C-h f} @%c(describe-function). La nueva versión
   utiliza un condicional para determinar si se ha reducido el búfer.

   (También, utiliza @c{line-number-at-pos}, que entre otras expresiones
   sencillas, como @c{(goto-char (point-min))}, mueve el punto al inicio de la
   línea actual con @c{(forward-line 0)} en lugar de @c{beginning-of-line}.)

   La función @c{what-line} que se muestra aqui tiene una línea de documentación
   y es interactiva, como es de esperar. Las dos líneas siguientes utilizan las
   funciones @c{save-restriction} y @c{widen}.

   La forma especial @c{save-restriction} observa cualquier reduccion activa en
   el buffer actual y restaura la reduccion despues de evaluar el código de su
   cuerpo.

   La forma especial @c{save-restriction} es seguida por @c{widen}. Esta función
   deshace cualquier reduccion que pudiera haber tenido el búfer actual cuando se
   llama a @c{what-line}. (La reduccion que estaba alli es la reduccion que
   @c{save-restriction} recuerda.) Esta ampliación hace posible que los comandos
   para el conteo de lineas cuenten desde el inicio del búfer. De lo contrario,
   se habría limitado a contar dentro de la región accesible. Cualquier
   reduccion original se restaura justo antes de completar la funcion por la
   forma especial @c{save-restriction}.

   La llamada a @c{widen} es seguida por @c{save-excursion}, que guarda la
   posición del cursor (es decir, el punto) y la marca, y los restaura después
   de que el código en el cuerpo de @c{save-excursion} utiliza la
   función @c{beginning-of-line} para mover el punto.

   (Ten en cuenta que la expresión @c{(widen)} ocurre entre las formas
   especiales @c{save-restriction} y @c{save-excursion}. Cuando escribas las dos
   expresiones @c{save-…} consecutivamente, escribe @c{save-excursion} primero.)

   Las dos últimas líneas de la función @c{what-line} son funciones para contar
   el número de líneas en el búfer y luego imprimir el número en el área de eco.

   ..src > elisp
     (message "Line %d"
              (1+ (count-lines 1 (point)))))))
   < src..

   La función @c{message} imprime un mensaje de una línea en la parte inferior
   de la pantalla de Emacs. El primer argumento esta dentro de comillas y se
   imprime como una cadena de caracteres. Sin embargo, contiene una expresión
   @'c{%d} para imprimir el siguiente argumento. @'c{%d} imprime el argumento como
   un decimal, por lo que el mensaje dirá algo como @'c{Línea 243}.

   El número que se imprime en lugar del @'{%d} se calcula por la última línea
   de la función:

   ..src > elisp
     (1+ (count-lines 1 (point)))
   < src..

   Lo que esto hace es contar las líneas desde la primer posición del búfer
   indicada por el @c{1}, hasta @c{(point)}, y luego sumar uno a este número.
   (La función @c{1+} suma uno a su argumento.) Se suma uno porque la línea 2
   tiene solo una línea antes de ella, y @c{count-lines} cuenta solo las líneas
   @e{antes} de la línea actual.

   Después que @c{count-lines} termina su trabajo, y se imprime el mensaje en el
   área de eco, la función @c{save-excursion} restaura el punto y marca a sus
   posiciones originales; y @c{save-restriction} restaura la reduccion original,
   si la hubiera.

** Ejercicio con Reduccion

   Escribe una función que muestre los primeros 60 caracteres del búfer actual,
   incluso si has reducido el búfer a la mitad de modo que la primer línea sea
   inaccesible. Restaura el punto, marca y la reduccion. Para este ejercicio,
   necesitas utilizar todo un popurri de funciones, incluyendo
   @c{save-restriction}, @c{widen}, @c{goto-char}, @c{point-min}, @c{message}, y
   @c{buffer-substring}.

   (@c{buffer-substring} es una función que aun no se menciona, tendrás que
   investigarla por tu cuenta; o quizás tengas que utilizar
   @c{buffer-substring-no-properties} o @c{filter-buffer-substring} …, u otras
   funciones. Las propiedades de texto son una funcionalidad que no sera
   discutida aquí. Consulta la Seccion @l{elisp.html#Text Properties<>Propiedades de
   Texto} en @e(El Manual de Referencia de Emacs Lisp).)

   Además, ¿realmente se necesita @c{goto-char} o @c{point-min}?  ¿O se puede
   escribir la función sin ellas?

* @c{car}, @c{cdr}, @c{cons}: Funciones fundamentales

  En Lisp, @c{car}, @c{cdr}, y @c{cons} son funciones fundamentales. La función
  @c{cons} se utiliza para construir listas, y las funciones @c{car} y @c{cdr}
  se utilizan para desmontarlas.

  En el recorrido a través de la función @c{copy-region-as-kill}, veremos @c{cons},
  asi como dos variantes de @c{cdr}, llamadas @c{setcdr} y @c{nthcdr}. (Consulta la
  Sección @l{#@c{copy-region-as-kill}}.)

  El nombre de la función @c{cons} no es irazonable: es una abreviatura de la
  palabra ‘construct’ @%i(construir). Por otra parte, el origen de los nombres
  @c{car} y @c{cdr}, es esoterico: @c{car} es un acrónimo de la frase @'b(Contents
  of the Address part of the Register) @%i(Contenidos de las Direcciónes parte
  del Registro); y @c{cdr} (pronunciado ‘could-er’) es un acrónimo de la frase
  @'b(Contents of the Decrement part of the Register) @%i(Contenidos de la parte de
  Decremento del Registro). Estas frases se refieren a piezas específicas de
  hardware en el ordenador en el que se desarrollo el Lisp original. Ademas de
  ser obsoletas, las frases han sido completamente irrelevantes por más de 25
  años para cualquiera que piense en Lisp. No obstante, aunque algunos pocos
  académicos valientes han empezado a utilizar nombres más razonables para estas
  funciones, los viejos términos aun continuan en uso. En particular, dado que los
  términos se utilizan en el código fuente de Emacs Lisp, los usaremos en esta
  introducción.

** @c{car} y @c{cdr}

   El @c{car} de una lista es sencillamente, el primer elemento de la lista. De
   este modo, el @c{car} de la lista @c{(rosa violeta margarita tulipan)} es
   @c{rosa}.

   Si estás leyendo esto dentro de GNU Emacs, puedes verlo evaluando lo siguiente:

   ..src > elisp
     (car '(rosa violeta margarita tulipan))
   < src..

   Después de evaluar la expresión, aparecerá @c{rosa} en el área de eco.

   Claramente, un nombre más razonable para la función @c{car} sería @c{first} y
   esto es con frecuencia lo que se sugiere.

   @c{car} no elimina el primer elemento de la lista; solo informa de lo que
   es. Después de aplicar @c{car} a una lista, la lista sigue siendo la misma
   que antes. En la jerga, @c{car} es ‘no destructiva’. Esta caracteristica
   resulta ser importante.

   El @c{cdr} de una lista es el resto de la lista, es decir, la función @c{cdr}
   devuelve la parte de la lista que sigue al primer elemento. Por lo tanto,
   mientras que el @c{car} de la lista @c{'(rosa violeta margarita tulipan)} es
   @c{rosa}, el resto de la lista, el valor devuelto por la función @c{cdr}, es
   @c{(violeta margarita tulipan)}.

   Puedes ver esto evaluando lo siguiente del modo habitual:

   ..src > elisp
     (cdr '(rosa violeta margarita tulipan))
   < src..

   Al evaluar esto, aparece @c{(violeta margarita tulipan)} en el área de eco.

   Al igual que @c{car}, @c{cdr} no elimina los elementos de la
   lista––simplemente devuelve un informe de lo que son el segundo y los
   elementos siguientes.

   A propositio, en el ejemplo, se cita la lista de las flores. De otra forma, el
   intérprete Lisp intentaría evaluar la lista llamando a @c{rosa} como una
   función. En este ejemplo, no queremos hacer esto.

   Claramente, un nombre más razonable para @c{cdr} sería @c{rest} @%i(resto).

   (Hay una lección aquí: Cuando des nombre a nuevas funciones, considera muy
   cuidadosamente lo que estes haciendo, ya que puedes adherirte a los nombres
   mas tiempo del esperado. La razón por la que este documento perpetúa estos
   nombres se debe a que el código fuente de Emacs Lisp los utiliza, y de no usarlos,
   tendrias dificultades para leer el codigo; por favor, intenta evitar usar
   estos términos por tu cuenta. Las personas que vengan después te lo
   agradecerán.

   Cuando se aplican @c{car} y @c{cdr} a una lista compuesta por símbolos, como
   la lista @c{(pino abeto roble arce)}, el elemento de la lista devuelto por la
   función @c{car} es el símbolo @c{pino} sin ningun paréntesis alrededor.
   @c{pino} es el primer elemento en la lista. Sin embargo, el @c{cdr} de la
   lista es una lista en si misma, @c{(abeto roble arce)}, como puedes observar al
   evaluar las siguientes expresiones:

   ..src > elisp
     (car '(pino abeto roble arce))

     (cdr '(pino abeto roble arce))
   < src..

   Por otro lado, en una lista de listas, el primer elemento es en sí mismo una
   lista. @c{car} devuelve este primer elemento como una lista. Por ejemplo, la
   siguiente lista contiene tres sub-listas, una lista de carnívoros, una lista
   de herbívoros y una lista de mamíferos:

   ..src > elisp
     (car '((leon tigre leopardo)
            (gacela antilope cebra)
            (ballena delfin foca)))
   < src..

   En este ejemplo, el primer elemento de @c{car} de la lista es la lista de
   carnívoros, @c{(leon tigre leopardo)}, y el resto de la lista es
   @c{((gacela antilope cebra) (ballena delfin foca))}.

   ..src > elisp
     (cdr '((leon tigre leopardo)
            (gacela antilope cebra)
            (ballena delfin foca)))
   < src..

   vale la pena decir nuevamente que @c{car} y @c{cdr} son no destructivos––es
   dicir, no modifican ni cambian las listas a las que se aplican. Esto es muy
   importante para la forma en que se utilizan.

   En el primer capítulo, en la discusión sobre los átomos, dije que en Lisp,
   “ciertos tipos de átomos, como un arreglo, pueden ser separados en partes;
   pero el mecanismo para hacer esto es diferente del mecanismo para separar una
   lista. Para Lisp, los átomos de una lista son indivisibles.” (Consulta la Seccion
   @l{#Átomos Lisp}.) Las funciones @c{car} y @c{cdr} se utilizan para dividir
   listas y se consideran fundamentales en Lisp. Ya que no se puede dividir o
   tener acceso a las partes de un arreglo, un arreglo se considera un
   átomo. Por otro lado, la otra función fundamental, @c{cons}, puede armar o
   construir una lista, pero no un arreglo. (Los arreglos se manejan mediante
   funciones especificas de arreglos. Consulta la Seccion
   @l{elisp.html#Arrays<>Arreglos} en el @e(El Manual de Referencia de GNU Emacs
   Lisp).)

** @c{cons}

   La función @c{cons} construye listas; que es lo opuesto a @c{car} y @c{cdr}.
   Por ejemplo, se puede utilizar @c{cons} para hacer una lista de cuatro elementos
   de la lista de tres elementos, @c{(abeto roble arce)}:

   ..src > elisp
     (cons 'pino '(abeto roble arce))
   < src..

   Después de evaluar esto, veras

   ..src > elisp
     (pino abeto roble arce)
   < src..

   aparecer en el área de eco. @c{cons} produce una nueva lista en la que el elemento es
   seguido por los elementos de la lista original.

   Con frecuencia decimos que ‘@c{cons} coloca un nuevo elemento al principio de
   una lista; que agrega o empuja el elemento en la lista’, pero esta frase
   puede ser engañosa, ya que @c{cons} no modifica una lista existente, sino que
   crea una nueva.

   Al igual que @c{car} y @c{cdr}, @c{cons} es no destructivo.

   @c{cons} debe tener una lista a unir.@n{9} No puedes iniciar de la nada
   absoluta. Si estás construyendo una lista, es necesario proporcionar al menos
   una lista vacía al inicio. Aquí hay una serie de expresiones @c{cons} que
   construyen una lista de flores. Si está leyendo esto en GNU Emacs, puedes
   evaluar cada una de las expresiones para corroborar el resultado.

   ..srci > elisp
     > (cons 'tulipan ())
     (tulipan)
     > (cons 'margarita '(tulipan))
     (margarita tulipan)
     > (cons 'violeta '(margarita tulipan))
     (violeta margarita tulipan)
     > (cons 'rosa '(violeta margarita tulipan))
     (rosa violeta margarita tulipan)
   < srci..

   En el primer ejemplo, la lista vacía se muestra como @c{()} y se construye
   una lista compuesta por @c{tulipan} seguida por la lista vacía. Como puedes
   ver, la lista vacía no se muestra en la lista que se construyo. Todo lo que
   ves es @c{(tulipan)}. La lista vacía no cuenta como un elemento de una
   lista porque no hay nada en una lista vacía. En terminos generales, una lista
   vacía es invisible.

   El segundo ejemplo, @c{(cons 'margarita '(tulipan))} construye una nueva
   lista de dos elemento colocando @c{margarita} delante de @c{tulipan}; y el
   tercer ejemplo construye una lista de tres elementos colocando @c{violeta}
   delante de @c{margarita} y @c{tulipan}.

*** Descubrir la longitud de una lista: @c{length}

    Puedes averiguar cuántos elementos hay en una lista utilizando la función
    Lisp @c{length}, como en los siguientes ejemplos:

    ..srci > elisp
      > (length '(tulipan))
      1
      > (length '(margarita tulipan))
      2
      > (length (cons 'violeta '(margarita tulipan)))
      3
    < srci..

    En el tercer ejemplo, la función @c{cons} se utiliza para construir una
    lista de tres elementos que se pasa como argumento a la función @c{length}.

    También podemos utilizar @c{length} para contar el número de elementos en
    una lista vacía:

    ..srci > elisp
      > (length ())
      0
    < srci..

    Como era de esperar, el número de elementos en una lista vacía es cero.

    Un experimento interesante es averiguar qué ocurre si se intenta encontrar
    la longitud de ninguna lista; es decir, si se intenta llamar a @c{length}
    sin darle un argumento, ni siquiera una lista vacía:

    ..src > elisp
      (length )
    < src..

    La que se ve, si evalúas esto, es el mensaje de error

    ..example >
      Lisp error: (wrong-number-of-arguments length 0)
    < example..

    Esto significa que la función recibe un número incorrecto de argumentos,
    cero, cuando se espera otro número de argumentos. En este caso, se
    espera un argumento, el argumento es una lista cuya longitud mide la
    función. (Ten en cuenta que @e{una} lista es @e{un} argumento, incluso si la
    lista tiene muchos elementos en su interior.)

    La parte del mensaje de error que dice @'{length} es el nombre de la
    función.

** @c{nthcdr}

   La función @c{nthcdr} esta asociada a la función @c{cdr}. Lo que hace es tomar
   el @c{cdr} de una lista repetidamente.

   Si tomas el @c{cdr} de la lista @c{(pino abeto roble arce)}, te devuelve la
   lista @c{(abeto roble arce)}. Si repites esto al retorno, devolverá la lista
   @c{(roble arce)}. (Por supuesto, repetir @c{cdr} en la lista original solo
   dará el @c{cdr} original, ya que la función no cambia la lista. Necesitas
   evaluar el @c{cdr} del @c{cdr} y así sucesivamente.) Si esto contiúa,
   finalmente se devuelve una lista vacía, que en este caso, en vez de mostrarse
   como @c{()} se muestra como @c{nil}.

   Para comprobarlo, aquí hay una serie de @c{cdr}s repetidos.

   ..srci > elisp
     > (cdr '(pino abeto roble arce))
     (abeto roble arce)
     > (cdr '(abeto roble arce))
     (roble arce)
     > (cdr '(roble arce))
     (arce)
     > (cdr '(arce))
     nil
     > (cdr 'nil)
     nil
     > (cdr ())
     nil
   < srci..

   También puedes hacer varios @c{cdr}s sin imprimir los valores intermedios, de
   esta forma:

   ..srci > elisp
     > (cdr (cdr '(pino abeto roble arce)))
     (roble arce)
   < srci..

   En este ejemplo, el intérprete Lisp primero evalúa la lista mas interna. La
   lista mas interna se cita, por lo que solo pasa la lista tal cual al @c{cdr}
   interno. Este @c{cdr} pasa una lista formada por el segundo y los subsiguientes
   elementos de la lista al @c{cdr} externo, que produce una lista compuesta del
   tercer y los subsiguientes elementos de la lista original. En este ejemplo, la
   función @c{cdr} se repite y devuelve una lista que consiste en la lista
   original sin sus primeros dos elementos.

   La función @c{nthcdr} hace lo mismo que repetir la llamada a @c{cdr}. En el
   siguiente ejemplo, el argumento 2 se pasa a la función @c{nthcdr}, junto con
   la lista, y el valor devuelto es la lista sin sus dos primeros elementos, que
   es exactamente lo mismo que repetir dos veces @c{cdr} en la lista:

   ..srci > elisp
     > (nthcdr 2 '(pino abeto roble arce))
     (roble arce)
   < srci..

   Utilizando la lista original de cuatro elementos, podemos ver qué ocurre
   cuando se pasan varios argumentos numéricos a @c{nthcdr}, incluyendo 0,
   1, y 5:

   ..srci > elisp
     > ;; Deja la lista como estaba.
     > (nthcdr 0 '(pino abeto roble arce))
     (pino abeto roble arce)
     > ;; Regresa una copia sin el primer elemento.
     > (nthcdr 1 '(pino abeto roble arce))
     (abeto roble arce)
     > ;; Regresa una copia de la lista sin tres elementos.
     > (nthcdr 3 '(pino abeto roble arce))
     (arce)
     > ;; Regresa una copia sin los cuatro elementos.
     > (nthcdr 4 '(pino abeto roble arce))
     nil
     > ;; Regresa una copia sin todos los elementos.
     > (nthcdr 5 '(pino abeto roble arce))
     nil
   < srci..

** @c{nth}

   La función @c{nthcdr} toma el @c{cdr} de una lista repetidamente. La función
   @c{nth} toma el @c{car} del resultado devuelto por @c{nthcdr}. Devuelve el
   enesimo elemento de la lista.

   Por lo tanto, si @c{nth} no estubiera definido en C por velocidad, su
   definición sería:

   ..src > elisp
     (defun nth (n list)
       "Devuelve el N-esimo elemento de la lista.
     N cuenta apartir de cero. Si LIST no es tan largo, devuelve nil."
       (car (nthcdr n list)))
   < src..

   (Originalmente, @c{nth} se definio en Emacs Lisp dentro de @f{subr.el}, pero
   su definición fué rehecha en C en la decada de 1980.)

   La función @c{nth} devuelve un solo elemento de una lista. Esto puede ser muy
   conveniente.

   Observa que los elementos estan numerados apartir del cero, no de
   uno. Es decir, el primer elemento de una lista, su @c{car} es el elemento
   cero. Esto se llama contar ‘basado en cero’ y con frecuencia molesta a las
   personas que estan acostumbradas a que el primer elemento de una lista sea el
   número uno, que es ‘basado en uno’.

   Por ejemplo:

   ..srci > elisp
     > (nth 0 '("uno" "dos" "tres"))
     "uno"
     > (nth 1 '("uno" "dos" "tres"))
     "dos"
   < srci..

   Vale la pena mencionar que @c{nth}, al igual que @c{nthcdr} y @c{cdr}, no
   modifica la lista original––la función es no destructiva. Esto contrasta
   fuertemente con las funciones @c{setcar} y @c{setcdr}.

** @c{setcar}

   Como podrías adivinar por sus nombres, las funciones @c{setcar} y
   @c{setcdr} establecen el @c{car} o el @c{cdr} de una lista a un nuevo
   valor. Ambos cambian realmente la lista original, a diferencia de @c{car} y
   @c{cdr} que dejan la lista original como estaba. Una forma de averiguar cómo
   funcionan es experimentar. Vamos a empezar con la función @c{setcar}.

   Primero, podemos crear una lista y luego asignar el valor de una variable a
   la lista, usando la función @c{setq}. Aquí hay una lista de animales:

   ..src > elisp
     (setq animales '(antilope jirafa leon tigre))
   < src..

   Si estás leyendo esto dentro de GNU Emacs, puedes evaluar esta expresión de
   la forma habitual, coloca el cursor después de la expresión y presiona @k{C-x
   C-e}. (Estoy haciendo esto aqui mismo, mientras lo escribo. Esta es una de
   las ventajas de tener el intérprete construido dentro del entorno informatico.
   Por cierto, cuando no hay nada en la línea después del paréntesis final, como
   un comentario, el punto puede estar en la siguiente línea. De este modo, si
   tu cursor está en la primera columna de la siguiente línea, no es necesario
   moverlo. En realidad, Emacs permite cualquier cantidad de espacios en blanco
   después del paréntesis final.)

   Cuando evaluamos la variable @c{animales}, vemos que está unida a la lista
   @c{(antilope jirafa leon tigre)}:

   ..srci > elisp
     > animales
     (antilope jirafa leon tigre)
   < srci..

   Dicho de otro modo, la variable @c{animales} apunta a la lista @c{(antilope
   jirafa leon tigre)}.

   A continuacion, evalua la función @c{setcar} mientras le pasas dos
   argumentos, la variable @c{animales} y el símbolo citado @c{hipopotamo}; esto
   se hace escribiendo una lista de tres elementos @c{(setcar animales
   'hipopotamo)}. Evaluala de la forma habitual:

   ..src > elisp
     (setcar animales 'hipopotamo)
   < src..

   Después de evaluar esta expresión, evalúa la variable @c{animales} de
   nuevo. Veras que la lista de animales ha cambiado:

   ..srci > elisp
     > animales
     (hipopótamo jirafa leon tigre)
   < srci..

   El primer elemento de la lista, @c{antilope} fue reemplazado por
   @c{hipopotamo}.

   Así podemos ver que @c{setcar} no agrega un nuevo elemento a la lista como
   haria @c{cons}; Se reemplaza @c{antílope} con @c{hipopótamo}; esto @e{cambia}
   la lista.

** @c{setcdr}

   La función @c{setcdr} es similar a la función @c{setcar}, excepto que la
   función reemplaza el segundo y subsiguientes elementos de una lista en lugar
   del primer elemento.

   (Para ver cómo cambiar el último elemento de una lista, mira directamente en
   la Seccion @l{#La función @c{kill-new}}, que utiliza las funciones @c{nthcdr}
   y @c{setcdr}.)

   Para ver cómo funciona esto, asigna el valor de la variable a una lista de
   animales domesticados evaluando la siguiente expresión:

   ..src > elisp
     (setq animales-domesticados '(caballo vaca oveja cabra))
   < src..

   Si evalúas la lista, debe devolverte la lista @c{(caballo vaca oveja cabra)}:

   ..srci > elisp
     > animales-domesticados
     (caballo vaca oveja cabra)
   < srci..

   Luego, evalúa @c{setcdr} con dos argumentos, el nombre de la variable que
   tiene una lista como su valor, y la lista a la que se establecera el @c{cdr}
   de la primera lista;

   ..src > elisp
     (setcdr animales-domesticados '(gato perro))
   < src..

   Si evalúas esta expresión, la lista @c{(gato perro)} aparecerá en el área
   echo. Este es el valor devuelto por la función. El resultado que nos interesa
   es el “efecto secundario”, que podemos ver evaluando la variable
   @c{animales-domesticados}:

   ..srci > elisp
     > animales-domesticados
     (caballo gato perro)
   < srci..

   En efecto, la lista cambia de @c{(caballo vaca oveja cabra)} a @c{(caballo
   gato perro)}. El @c{cdr} de la lista cambia de @c{(vaca oveja cabra)} a
   @c{(gato perro)}.

** Ejercicio

   Construye una lista de cuatro pájaros evaluando varias expresiones con
   @c{cons}. Descubre que ocurre cuando aplicas @c{cons} a una lista sobre si
   misma. Reemplaza el primer elemento de la lista de cuatro pájaros con un
   pez. Reemplaza el resto de esta lista con una lista de otros peces.

* Cortar y Almacenar Texto

  Cada vez que se corta texto de un búfer con un comando ‘kill’, se almacena
  en una lista y puedes traerlo de vuelta con un comando ‘yank’.

  (El uso de la palabra ‘kill’ @%i(matar) en Emacs para procesos que
  específicamente @e{no} destruyen los valores de las entidades es un accidente
  histórico desafortunado. Una palabra mucho más apropiada seria ‘clip’
  @%i(recortar) ya que eso es lo que hacen los comandos @'(kill); recortan el
  texto de un búfer y lo almacenan para que puede traerse de vuelta. Con
  frecuencia me he sentido tentado a sustituir globalmente todas las apariciones
  de ‘kill’ en el codigo de Emacs con ‘clip’ y todas las apariciones de ‘killed’
  @%i(destruido) con ‘clipped’ @%i(cortado).)

  Cuando el texto se corta de un búfer, se almacena en una lista. Los fragmentos de
  texto se almacenan en la lista de forma sucesiva, por lo que la lista podría verse
  así:

  ..src > elisp
    ("una pieza de texto" "pieza anterior")
  < src..

  La función @c{cons} se puede utilizar para crear una nueva lista a partir de
  un trozo de texto (un ‘átomo’, para usar la jerga) y una lista existente,
  como esta:

  ..src > elisp
    (cons "otra pieza"
          '("una pieza de texto" "pieza anterior"))
  < src..

  Si evaluas esta expresión, aparecera una lista de tres elementos en el área
  de eco:

  ..src > elisp
    ("otra pieza" "una pieza de texto" "pieza anterior")
  < src..

  Puedes recuperar cualquier pieza de texto que desees, con las funciones
  @c{car} y @c{nthcdr}. Por ejemplo, en el siguiente código, @c(nthcdr 1 …)
  devuelve la lista con el primer elemento eliminado; y @c{car} devuelve el
  primer elemento de ese resto––el segundo elemento de la lista original:

  ..srci > elisp
    > (car (nthcdr 1 '("otra pieza"
    ^                  "una pieza de texto"
    ^                  "pieza anterior")))
    "una pieza de texto"
  < srci..

  Por supuesto, las funciones reales en Emacs son más complejas que esto. El
  código para el corte y recuperarcion de texto tiene que ser escrito de modo
  que Emacs pueda determinar qué elemento en la lista se quiere––el primero,
  segundo, tercero o cualquier otro. Además, cuando se llega al final de la
  lista, Emacs deberia darte el primer elemento de la lista, en lugar de nada en
  absoluto.

  La lista que contiene los trozos de texto se llama @:(kill ring) @%i(anillo de
  la muerte). En este capítulo se hace una descripción del anillo de la muerte y
  como se utiliza en un primer vistazo a la función @c{zap-to-char}. Esta
  función utiliza (o ‘llama’) a una función que invoca a otra función que
  manipula el anillo de la muerte. Por la tanto, antes de llegar a las montañas,
  debemos escalar las colinas.

  En un capítulo posterior se describe cómo se recupera el texto que se corta de
  un buffer. Consulta la Sección @l{#Traer de regreso el texto}.

** @c{zap-to-char}

   La función @c{zap-to-char} apenas ha variado entre la versión 19 y 22 de GNU
   Emacs. Sin embargo, @c{zap-to-char} llama a otra función, @c{kill-region},
   que ha tenido una importante reescritura.

   La función @c{kill-region} en Emacs 19 es compleja, pero no utiliza código
   que sea importante en este momento. Nos Lo saltaremos.

   La función @c{kill-region} en Emacs 22 es más fácil de leer que la misma
   función en Emacs 19 e introduce un concepto muy importante, la gestion de
   errores. Caminaremos a través de la función.

   Pero primero, veamos la función interactiva @c{zap-to-char}.

   La función @c{zap-to-char} elimina el texto en la región entre la ubicacion
   del cursor (es decir, del punto) hasta e incluyendo la siguiente aparicion de
   un caracter específicado. El texto que @c{zap-to-char} elimina se pone en el
   anillo de la muerte; y se puede recuperar escribiendo @k{C-y} @%c(yank). Si
   el comando recive un argumento, elimina el texto a través de ese número de
   ocurrencias. Por lo tanto, si el cursor estuviera al inicio de esta frase y
   el carácter fuera @'{s}, se eliminaria @'{Por lo tanto, s}. Si el argumento
   fuera dos, se eliminaria @'{Por lo tanto, si el curs}, hasta e incluiendo la
   @'{s} en @'{cursor}.

   Si no se encuentra el carácter específicado @c{zap-to-char} dirá “Search
   failed” @%i(Búsqueda fallida), te indicaria el caracter que escribiste, y no
   eliminara ningun texto.

   Para determinar la cantidad de texto a eliminar @c{zap-to-char} utiliza una
   función de búsqueda. Las búsquedas se utilizan ampliamente en código que
   manipula el texto, y vamos a centrar la atención en ellos, asi como en el
   comando de eliminacion.

   Aquí está el texto completo de la función en la versión 22:

   ..src > elisp
     (defun zap-to-char (arg char)
       "Corta e incluye la aparicion de la enesima ocurrencia (ARG) del caracter CHAR.
     Se ignora entre mayusculas y minusculas si ‘case-fold-search’ es no-nil en
     el buffer actual.
     Retrocede si ARG es negativo; error si CHAR no se encuentra."
       (interactive "p\ncZap to char: ")
       (if (char-table-p translation-table-for-input)
           (setq char (or (aref translation-table-for-input char) char)))
       (kill-region (point) (progn
                              (search-forward (char-to-string char) nil nil arg)
                              (point))))
   < src..

   La linea de documentacion esta traducida al español. En la version original
   no se utiliza la palabra ‘Corta’ en su lugar se utiliza ‘kill’.

*** La expresión @c{interactive}

    La expresión interactiva en el comando @c{zap-to-char} es esta:

    ..src > elisp
      (interactive "p\ncZap to char: ")
    < src..

    La parte entre comillas, @c{"p\ncZap to char: "}, especifica dos cosas
    diferentes. Primero, y lo mas sencillo, es la @'c{p}. Esta parte se separa de
    la siguiente parte por una línea nueva, @'c{\n}. La @'c{p} significa que a el
    primer argumento de la función será pasando el valor de un ‘prefijo
    procesado’. El argumento prefijo se pasa escribiendo @k{C-u} y un número, o
    @k{M-} y un número. Si la función se llamada interactivamente sin un
    prefijo, se pasa 1 a este argumento.

    La segunda parte de @c{"p\ncZap to char: "} es @'c{cZap to char:}. En esta
    parte, la @'c{c} minuscula indica que @c{interactive} espera un prompt y que
    el argumento será un caracter. El prompt va despues de @'c{c} y es la cadena
    @'c{Zap to char: } (con un espacio después de los dos puntos para que se vea bien).

    Lo que todo esto hace es preparar los argumentos de @c{zap-to-char} para que
    sean del tipo correcto, y darle al usuario un prompt.

    En un búfer de solo lectura, la función @c{zap-to-char} copia el texto al
    anillo de la muerte, pero no lo elimina. El área de eco muestra un mensaje
    diciendo que el búfer es de solo lectura. Ademas, el terminal puede emitir
    un pitido o parpadear.

*** El cuerpo de @c{zap-to-char}

    El cuerpo de la función @c{zap-to-char} contiene el código que mata (es
    decir, elimina) el texto en la región desde la posición actual del cursor
    hasta e incluyendo el carácter especificado.

    La primera parte del código luce asi:

    ..src > elisp
      (if (char-table-p translation-table-for-input)
          (setq char (or (aref translation-table-for-input char) char)))
      (kill-region (point) (progn
                             (search-forward (char-to-string char) nil nil arg)
                             (point)))
    < src..

    @c{char-table-p} es una función que aun no hemos visto. Determina si su argumento
    es una tabla de caracteres. Si lo es, establece el caracter pasado a
    @c{zap-to-char} a uno de ellos, si ese carácter existe, o al carácter en
    sí. (Esto es importante para ciertos caracteres en idiomas no europeos. La
    función @c{aref} extrae un elemento desde un arreglo. Esta funcion es
    específica para arreglos y no sera descrita en este documento. Consulta la Seccion
    @l{elisp.html#Arrays<>Arreglos} en @e(El Manual de Referencia de GNU Emacs
    Lisp).)

    @c{(point)} es la posición actual del cursor.

    La siguiente parte del código es una expresión utilizando @c{progn}. El
    cuerpo de @c{progn} consiste en llamadas a @c{search-forward} y @c{point}.

    Es fácil comprender cómo funciona @c{progn} después de aprender sobre
    @c{search-forward}, asi que veremos @c{search-forward} y luego @c{progn}.

*** La Función @c{search-forward}

    La función @c{search-forward} se utiliza para localizar el caracter a borrar
    en @c{zap-to-char}. Si la búsqueda es exitosa, @c{search-forward} deja el
    punto inmediatamente después del último carácter en la cadena objetivo. (En
    @c{zap-to-char}, la cadena objetivo tiene solo un carácter longitud.
    @c{zap-to-char} usa la función @c{char-to-string} para asegurar que el
    computador trata este carácter como una cadena). Si la búsqueda es hacia
    atrás, @c{search-forward} deja el punto justo antes del primer carácter en
    el objetivo. Ademas, @c{search-forward} devuelve @c{t} para verdadero. (Por
    lo tanto, desplazar el punto es un ‘efecto secundario’.)

    En @c{zap-to-char}, la función @c{search-forward} se ve así:

    ..src > elisp
      (search-forward (char-to-string char) nil nil arg)
    < src..

    La función @c{search-forward} utiliza cuatro argumentos:

    1. El primer argumento es el objetivo, que esta buscando. Debe ser una
       cadena, como @c{"z"}.

       Sucede que el argumento pasado a @c{zap-to-char} es un solo
       caracter. Debido a la forma en la que se construyen los computadores, el
       intérprete Lisp puede tratar un solo caracter de forma distinta a una
       cadena de caracteres. Dentro del computador, un solo caracter tiene un
       formato electrónico diferente a una cadena de un caracteres. (Un solo
       caracter con frecuencia puede grabarse en el computador utilizardo
       exactamente un byte; pero una cadena puede ser mas larga, y el equipo
       debe estar listo para ello.) Ya que la función @c{search-forward} busca
       una cadena, el caracter que recive la función @c{zap-to-char} como
       argumento debe convertirse dentro del computador de un formato a otro; de
       lo contrario, la función @c{search-forward} fallará. Se utiliza la
       función @c{char-to-string} para realizar esta conversión.

    2. El segundo argumento limita la búsqueda; se especifica como una posición
       en el búfer. En este caso, la búsqueda puede ir al final del búfer, por
       lo que no se establece ningun limite y el segundo argumento es @c{nil}.

    3. El tercer argumento le dice a la función lo que debe hacer si la búsqueda
       falla––puede señalar un error (e imprimir un mensaje) o puede devolver
       @c{nil}. Un @c{nil} como el tercer argumento hace que la función señale
       un error cuando la búsqueda falla.

    4. El cuarto argumento de @c{search-forward} es el contador de
       repeticion––cuántas ocurrencias de la cadena hay que buscar. Este
       argumento es opcional y si la función se llamada sin contador de
       repeticion, este argumento pasa el valor 1. Si este argumento es
       negativo, la búsqueda va hacia atrás.


    En formato plantilla, una expresión @c{search-forward} tiene este aspecto:

    ..src > elisp
      (search-forward "cadena-a-buscar"
                      limite-de-busqueda
                      que-hacer-si-la-busqueda-falla
                      contador-de-repeticion)
    < src..

    A continuacion veremos @c{progn}.

*** La forma especial @c{progn}

    @c{progn} es una forma especial que hace que cada uno de sus argumentos sea
    evaluado en secuencia y luego devuelve el valor del último. Las expresiones
    anteriores solo se evaluan por los efectos secundarios que producen. Los
    valores producidos son descartados.

    La plantilla de una expresión @c{progn} es muy simple:

    ..src > elisp
      (progn
        cuerpo…)
    < src..

    En @c{zap-to-char}, la expresión @c{progn} tiene que hacer dos cosas: poner
    el punto exactamente en la posición correcta; y devolver la posición del
    punto para que @c{kill-region} sepa hasta donde cortar.

    El primer argumento de @c{progn} es @c{search-forward}. Cuando
    @c{search-forward} encuentra la cadena, la función deja el punto
    inmediatamente después del último caracter en la cadena objetivo. (En este
    caso la cadena objetivo tiene solo un carácter de longitud.) Si la búsqueda es
    hacia atrás, @c{search-forward} deja el punto justo antes del primer
    carácter objetivo. El movimiento del punto es un efecto secundario.

    El segundo y último argumento de @c{progn} es la expresión @c{(point)}. Esta
    expresión devuelve el valor del punto, que en este caso será la ubicacion a
    la que se ha desplazado por @c{search-forward}. (En el codigo, una línea le
    indicaba a la función que debia ir un carácter atras, si va hacia adelante, se
    comentó en 1999; yo no recuerdo si esta caracteriscita o funcion incorrecta
    alguna vez fue parte del codigo distribuido.) El valor de @c{point} es
    devuelto por la expresión @c{progn} y se pasa a @c{kill-region} como el
    segundo argumento de @c{kill-region} .

*** Resumiendo @c{zap-to-char}

    Ahora que hemos visto cómo funcionan @c{search-forward} y @c{progn}, podemos
    ver cómo la función @c{zap-to-como} trabaja como un todo.

    El primer argumento de @c{kill-region} es la posición del cursor cuando se
    da el comando @c{zap-to-char}––el valor de punto en ese momento. Dentro de
    @c{progn}, la funcion de búsqueda mueve el punto justo después del caracter
    a borrar y @c{point} devuelve el valor de esa ubicacion. La función
    @c{kill-region} reune estos dos valores de punto, el primero como el inicio
    de la región y el segundo como el final de la región, y elimina la región.

    La forma especial @c{progn} es necesaria porque el comando @c{kill-region}
    toma dos argumentos; y fallaría si las expresiones @c{search-forward} y
    @c{point} se escribieran en secuencia como dos argumentos adicionales. La
    expresión @c{progn} es solo un argumento para @c{kill-region} y devuelve el
    valor que @c{kill-region} necesita para su segundo argumento.

** @c{kill-region}

   La función @c{zap-to-char} utiliza la función @c{kill-region}. Esta función
   corta texto de una región y copia ese texto al anillo de la muerte, desde el
   que puede ser recuperado.

   La versión en Emacs 22 de esta funcion utiliza @c{condition-case} y
   @c{copy-region-as-kill}, ambas seran explicadas. @c{condition-case} es una
   forma especial importante.

   En esencia, la función @c{kill-region} llama a @c{condition-case}, que toma
   tres argumentos. En esta función, el primer argumento no hace nada. El
   segundo argumento contiene el código que hace el trabajo cuando todo va
   bien. El tercer argumento contiene el código que se llama en caso de error.

   Revisaremos el código de @c{condition-case} en un momento. Primero, veamos la
   definición de @c{kill-region}, con comentarios añadidos:

   ..src > elisp
     (defun kill-region (beg end)
       "Kill (\"corta\") el texto entre el punto y la marca.
     Esto elimina el texto del buffer y lo guarda en el anillo de la muerte.
     El comando \\[yank] puede recuperarlo desde alli. … "

       ;; • Puesto que el orden importa, primero pasa el punto.
       (interactive (list (point) (mark)))
       ;; • Y dinos si no podemos cortar el texto.
       ;; ‘unless’ es un ‘if’ sin parte-then.
       (unless (and beg end)
         (error "La marca no esta definida, asi que no hay ninguna region"))
       ;; • ‘condition-case’ toma tres argumentos.
       ;;    Si el primer argumento es nil, como aqui,
       ;;    la informacion del error no se almacena
       ;;    para ser utilizado por otra funcion.
       (condition-case nil

           ;; • El segundo argumento de ‘condition-case’ le dice al
           ;;    interprete Lisp que hacer cuando todo va bien.

           ;;    Empieza con una funcion ‘let’ que extrae la cadena y
           ;;    comprueba si existe. Si es asi (eso es lo que comprueba
           ;;    ‘when’), esta llama a una funcion ‘if’ que determina
           ;;    si el comando anterior fue otra llamada a ‘kill-region’;
           ;;    si lo fue, el nuevo texto se añade al texto anterior; si
           ;;    no, se llama a una funcion diferente, se llama a ‘kill-new’.

           ;;    La funcion ‘kill-append’ concatena la cadena nueva y antigua.
           ;;    La funcion ‘kill-new’ inserta el texto dentro de un nuevo
           ;;    elemento en el anillo de la muerte.

           ;;    ‘when’ es un ‘if’ sin una parte-else. El segundo ‘when’
           ;;    comprueba de nuevo si la cadena actual existe; Ademas,
           ;;    comprueba si el comando anterior fue otra llamada a
           ;;    ‘kill-region’. Si una u otra condicion es verdadera,
           ;;    entonces establece que el comando actual sea ‘kill-region’.
           (let ((string (filter-buffer-substring beg end t)))
             (when string                    ;STRING es nil si BEG = END
               ;; agrega esa cadena al anillo de la muerte, de uno forma u otra.
               (if (eq last-command 'kill-region)
                   ;;    − ‘yank-handler’ es un argumento opcional de
                   ;;    ‘kill-region’ que indica a las funciones ‘kill-append’
                   ;;    y ‘kill-new’ como tratar las propiedades añadidas al
                   ;;    texto, como ‘negrita’ o ‘cursiva’.
                   (kill-append string (< end beg) yank-handler)
                 (kill-new string nil yank-handler)))
             (when (or string (eq last-command 'kill-region))
               (setq this-command 'kill-region))
             nil)

         ;;  • El tercer argumento de ‘condition-case’ le dice al interprete
         ;;    que hacer con un error.
         ;;    El tercer argumento tiene una parte de condiciones y una parte cuerpo.
         ;;    Si se cumplen las condiciones (en este caso,
         ;;             si el texto o el buffer son de solo lectura)
         ;;    entonces se ejecuta el cuerpo.
         ;;    La primer parte del tercer argumento es la siguiente:
         ((buffer-read-only text-read-only) ;; la parte-if
          ;; …  la parte-then
          (copy-region-as-kill beg end)
          ;;    A continuacion, tambien como parte de la parte-then, establece
          ;;    this-command, por lo que se establece en un error
          (setq this-command 'kill-region)
          ;;    Finalmente, en la pante-then, envia un mensaje si puede copiar
          ;;    el texto en el anillo de la muerte sin señalar un error, pero
          ;;    no lo hace si no puede.
          (if kill-read-only-ok
              (progn (message "Read only text copied to kill ring") nil)
            (barf-if-buffer-read-only)
            ;; Si el buffer no es de solo lectura, el texto lo es.
            (signal 'text-read-only (list (current-buffer)))))
   < src..

*** @c{condition-case}

    Como se ha visto antes (Consulta la Seccion @l{#Generar un Mensaje de Error}), cuando
    el intérprete de Emacs Lisp tiene problemas evaluando una expresión, te
    proporciona ayuda; en la jerga, esto se llama “Señalar un error”.
    Normalmente, el computador detiene el programa y te muestra un mensaje.

    Sin embargo, algunos programas emprenden acciones complicadas. No deberian
    simplemente detenerse en un error. En la función @c{kill-region}, el error
    mas probable es que intente cortar texto que sea de solo lectura y no pueda
    ser eliminado. Así que la función @c{kill-region} contiene código para
    manejar esta circunstancia. Este código, que forma el cuerpo de la función
    @c{kill-region}, se encuentra dentro de una forma especial @c{condition-case}.

    La plantilla para @c{condition-case} tiene este aspecto:

    ..src > elisp
      (condition-case
        var
        bodyform
        gestor-de-errores…)
    < src..

    El segundo argumento, @c{bodyform} es sencillo. La forma especial
    @c{condition-case} hace que el intérprete Lisp evalúe el código en
    @c{bodyform}. Si no ocurre ningún error, la forma especial devuelve el valor
    del código y produce los efectos secundarios, si los hubiera.

    En resumen, la parte @c{bodyform} de una expresión @c{condition-case}
    determina qué deberia suceder cuando todo funciona correctamente.

    Sin embargo, si ocurre un error, entre otras acciones, la función
    genera la señal de error que define uno o más nombres de condicion de error.

    El gestor de errores es el tercer argumento de @c{condition-case}. Un gestor
    de errores tiene dos partes, un @c{nombre-de-condicion} y un @c{cuerpo}. Si
    la parte @c{nombre-de-condicion} de un gestor de errores coincide con un
    nombre de condicion generado por un error, se ejecuta la parte del
    @c{cuerpo} del gestor de errores.

    Como es de esperar, la parte @c{nombre-de-condicion} de un gestor de errores
    puede ser un unico nombre de condicion o una lista de nombres de condición.

    Ademas, una expresión @c{condition-case} completa puede contener más de un
    gestor de errores. Cuando se produce un error, se ejecuta el primer
    gestor aplicable.

    Por ultimo, el primer argumento de la expresión @c{condition-case}, el
    argumento @c{var}, en ocaciones se vincula a una variable que contiene
    información sobre el error. Sin embargo, si este argumento es @c(nil), como
    es el caso en @c{kill-region}, esa información se descarta.

    En resumen, en la función @c{kill-region}, el código @c{condition-case}
    funciona de la siguiente manera:

    ..example >
      Si no hay errores, ejecuta solo este codigo
          pero, si hay errores, ejecuta este otro codigo.
    < example..

*** Macro Lisp

    La parte de la expresión @c{condition-case} se evalúa con la expectativa
    de que todo va bien si tiene un @c{when}. El código utiliza @c{when} para
    determinar si la variable @c{string} apunta a texto que existe.

    Una expresión @c{when} simplemente es una conveniencia para los
    programadores. Es un @c{if} sin la posibilidad de una cláusula else. En tu
    mente, puedes reemplazar @c{when} con @c{if} y entender lo que pasa. Eso es
    lo que hace el intérprete Lisp.

    Técnicamente hablando, @c{when} es una macro Lisp. Una @:{macro} Lisp te
    permite definir nuevas construcciones de control y otras caracteristicas de
    lenguaje. Le indica al intérprete cómo calcular otra expresión Lisp que a su
    vez calculara el valor. En este caso, la ‘otra expresión’ es una expresión
    @c{if}.

    La definición de la función @c(kill-region) también tiene una macro
    @c{unless}; es lo contario de @c{when}. La macro @c{unless} es un @c{if} sin
    la cláusula @c(then).

    Para optener más informacion sobre las macros Lisp, consulta la Seccion
    @l{elisp.html#Macros<>Macros} en @e(El Manual de Referencia de Emacs
    Lisp). El lenguaje de programación C también proporciona macros. Estos son
    diferentes, pero también útiles.

    Respecto a la macro @c{when}, en la expresión @c{condition-case}, cuando la
    cadena tiene contenido, se ejecuta otra expresión condicional. Esto es un
    @c{if} tanto con la parte-then como con la parte-else.

    ..src > elisp
      (if (eq last-command 'kill-region)
          (kill-append string (< end beg) yank-handler)
        (kill-new string nil yank-handler))
    < src..

    La parte-then se evalúa si el comando anterior era otra llamada
    a @c{kill-region}; si no, se evalúa la parte-else.

    @c{yank-handler} es un argumento opcional de @c{kill-region} que indica a
    las funciones @c{kill-append} y @c{kill-new} como tratar con propiedades
    añadidas al texto, como ‘negrilla’ o ‘cursiva’.

    @c{last-command} es una variable que viene con Emacs y que no hemos visto
    antes. Normalmente, siempre que se ejecuta una función, Emacs establece el
    valor de @c{last-command} al comando anterior.

    En este segmento de la definición, la expresión @c{if} comprueba si el
    comando anterior fue @c{kill-region}. Si lo fuera,

    ..src > elisp
      (kill-append string (< end beg) yank-handler)
    < src..

    concatena una copia del texto recien cortado al texto cortado previamente en
    el anillo de la muerte.

** @c{copy-region-as-kill}

   La función @c{copy-region-as-kill} copia una región de texto de un búfer
   y (via @c{kill-append} o @c{kill-new}) lo guarda en el @c{kill-ring}.

   Si llamas a @c{copy-region-as-kill} inmediatamente después de un comando
   @c{kill-region}, Emacs agregara el texto recien copiado al texto copiado
   previamente. Esto significa que traes el texto, lo obtienes todo, tanto de
   esta operacion como de la anterior. Por otra parte, si algún otro comando
   precede a @c{copy-region-as-kill}, la función copia el texto dentro de una
   entrada separada en el anillo de la muerte.

   Aquí está el texto completo de la función @c{copy-region-as-kill} de la
   versión 22:

   ..src > elisp
     (defun copy-region-as-kill (beg end)
       "Guarda la region como si fuese cortada, pero no la corta.
     En el modo Transient Mark, desactiva la marca.
     Si ‘interprogram-cut-function’ es no-nil, tambien guarda el texto para un
     sistema de ventana cortar y pegar."
       (interactive "r")
       (if (eq last-command 'kill-region)
           (kill-append (filter-buffer-substring beg end) (< end beg))
         (kill-new (filter-buffer-substring beg end)))
       (if transient-mark-mode
           (setq deactivate-mark t))
       nil)
   < src..

   Como de costumbre, esta función puede dividirse en las partes que la
   componen:

   ..src > elisp
     (defun copy-region-as-kill (lista-de-argumentos)
       "documentacion…"
       (interactive "r")
       cuerpo…)
   < src..

   Los argumentos son @c{beg} y @c{end} y la función es interactiva con @c{"r"},
   por lo que los dos argumentos deben referirse al inicio y al final de la
   región. Si has estado leyendo este documento desde el principio, entender
   estas partes de una función se esta convirtiendo en algo rutinario.

   En la documentación, los comentarios de ‘Transient Mark’ e
   @c{interprogram-cut-function} explican ciertos efectos secundarios.

   Después de establecer una marca, un búfer siempre contiene una región. Si lo
   deseas puedes utilizar el modo Transient Mark para resaltar temporalmente la
   región. (Nadie quiere resaltar la región todo el tiempo, por lo que el modo
   Trasient Mark lo resalta solo en los momentos apropiados. Muchas personas
   desactivan el modo Transient Mark, por lo que la región nunca se resalta.)

   Ademas, un sistema de ventanas permite copiar, cortar y pegar entre diferentes
   programas. En el sistema de ventanas X, por ejemplo, la función
   @c{interprogram-cut-function} es @c{x-select-text}, que funciona con el
   sistema de ventanas equivalente al anillo de la muerte de Emacs.

   El cuerpo de la función @c{copy-region-as-kill} inicia con una cláusula
   @c{if}. Lo que esta cláusula hace es distinguir entre dos situaciones
   diferentes: si este comando se ejecuta o no inmediatamente después de un
   comando @c{kill-region} anterior. En el primer caso, la nueva región se
   concatena al texto copiado previamente. De lo contrario, se inserta al inicio
   del anillo de la muerte como una pieza de texto separada de la anterior.

   Las dos ultimas líneas de la función impiden que la región se ilumine si el
   modo Transient Mark está activo.

   El cuerpo de @c{copy-region-as-kill} merece ser discutido en detalle.

*** El cuerpo de @c{copy-region-as-kill}

    @c{copy-region-as-kill} funciona de un modo parecido a la función
    @c{kill-region}. Ambas están escritas de manera que dos o más cortes en una
    fila combinan su texto en una sola entrada. Si sacas el texto del anillo de
    la muerte, se optiene todo en una sola pieza. Ademas, las funciones que cortan
    hacia adelante desde la posición actual del cursor se añaden al final del
    texto copiado previamente y los comandos que cortan el texto hacia atrás lo
    añaden al principio del texto copiado previamente. De esta manera, las
    palabras del texto permanecen en el orden correcto.

    Al igual que @c{kill-region}, la función @c{copy-region-as-kill} hace uso de
    la variable @c{last-command} que mantiene un seguimiento del comando Emacs
    anterior.

    Normalmente, siempre que se ejecuta una función, Emacs asigna el valor de
    @c{this-command} a la función que se esta ejecutando (que en este caso sería
    @c{copy-region-as-kill}). Al mismo tiempo, Emacs asigna el valor de
    @c{last-command} al valor anterior de @c{this-command}.

    En la primer parte del cuerpo de la función @c{copy-region-as-kill}, una
    expresión @c{if} determina si el valor de @c{last-command} es
    @c{kill-region}. Si es así, se evalua la parte-then de la expresión @c{if};
    utiliza la función @c{kill-append} para concatenar el texto copiado en la llamada
    a esta función con el texto que ya esta en el primer elemento (el @c{car} del
    anillo de la muerte. Por otro lado, si el valor de @c{last-command} no es
    @c{kill-region}, entonces la función @c{copy-region-as-kill} asigna un nuevo
    elemento al anillo de la muerte usando la función @c{kill-new}.

    La expresión @c{if} se lee de la siguiente manera; utiliza @c{eq}:

    ..src > elisp
      (if (eq last-command 'kill-region)
          ;; parte-then
          (kill-append  (filter-buffer-substring beg end) (< end beg))
        ;; parte-else
        (kill-new  (filter-buffer-substring beg end)))
    < src..

    (La función @c{filter-buffer-substring} devuelve una subcadena filtrada del
    búfer, si existe. Opcionalmente––los argumentos no están aquí, por lo que
    tampoco se hace––la función puede borrar el texto inicial o devolver el
    texto sin sus propiedades; esta función es un reemplazo para la antigua
    función @c{buffer-substring}, que existia antes de que se implementaran las
    propiedades del texto.)

    La función @c{eq} comprueba si su primer argumento es el mismo objeto Lisp que
    su segundo argumento. La función @c{eq} es similar a la función @c{equal}
    que se utiliza para probar la igualdad, pero difiere en que determina si dos
    representaciones son realmente el mismo objeto dentro de la computadora,
    pero con nombres diferentes. @c{equal} determina si la estructura y el
    contenido de dos expresiones son iguales.

    Si el comando anterior fue @c{kill-region}, entonces el intérprete Emacs
    Lisp llama a la función @c{kill-append}

**** La función @c{kill-append}

     La función @c{kill-new} se ve así:

     ..src > elisp
       (defun kill-append (string before-p &optional yank-handler)
         "Inserta STRING al fin del ultimo corte en el anillo de la muerte.
       Si BEFORE-P no es nil, anexa STRING al corte.
       … "
         (let* ((cur (car kill-ring)))
           (kill-new (if before-p (concat string cur) (concat cur string))
                     (or (= (length cur) 0)
                         (equal yank-handler
                                (get-text-property 0 'yank-handler cur)))
                     yank-handler)))
     < src..

     La función @c{kill-append} es bastante sencilla. Utiliza la función
     @c{kill-new}, que discutiremos con más detalle en un momento.

     (Ademas, la función proporciona un argumento opcional llamado
     @c{yank-handler}; cuando se invoca, este argumento le dice a la función
     cómo tratar con la propiedades añadidas al texto, como ‘negrita’ o
     ‘cursiva’.)

     Tiene una función @c{let*} para asignar el valor del primer elemento del
     anillo de la muerte a @c{cur}. (No se por qué la función no utiliza @c{let}
     en su lugar; solo un valor se asigna en la expresión. ¿Tal vez este es un
     bug que no produce problemas?

     Examinemos el condicional proporciana uno de los dos argumentos de @c{kill-new}.
     Utiliza @c{concat} para concatenar el nuevo texto al @c{car} del anillo de
     la muerte. Si agrega el texto antes o despues depende del resultado de la
     expresión @c{if}:

     ..src > elisp
       (if before-p                            ; parte-if
           (concat string cur)                 ; parte-then
         (concat cur string))                  ; parte-else
     < src..

     Si la región a cortar está antes de la región que se cortó en el último
     comando, entonces debería ser puesta antes que el material guardado en el
     corte anterior; y, a la inversa, si el texto que se corto esta despues del
     que se acaba de cortar, debe añadirse después del texto anterior. La expresión
     @c{if} depende del predicado @c{before-p} para decidir si el texto recien
     guardado debe colocarse antes o después del texto anterior.

     El símbolo @c{before-p} es el nombre de uno de los argumentos para
     @c{kill-append}. Cuando se evalúa la función @c{kill-append}, se asocia al
     valor devuelto evaluando el argumento actual. En este caso, esta es la
     expresión @c{(< end beg)}. Esta expresión no determina directamente si el
     texto cortado en este comando se localiza antes o después del texto cortado
     del último comando; lo que hace es determinar si el valor de la variable
     @c{end} es menor que el valor de la variable @c{beg}. Si es así, significa
     que problamemente el usuario se dirige hacia el principio del búfer. Ademas, el
     resultado de evaluar la expresión del predicado. @c{(< end beg)}, será
     verdadero y el texto se concatena antes del texto anterior. Por otro lado,
     si el valor de la variable @c{end} es mayor que el valor del la variable
     @c{beg}, el texto se agregara después del texto anterior.

     Cuando el texto recien guardado se antepone, la cadena con el nuevo texto se
     concatena antes que el texto anterior:

     ..src > elisp
       (concat string cur)
     < src..

     Pero si el texto será añadido, será concatenado después del texto anterior:

     ..src > elisp
       (concat cur string))
     < src..

     Para entender cómo funciona esto, primero necesitamos revisar la
     función @c{concat}. La función @c{concat} enlaza o une dos cadenas
     de texto. El resultado es una cadena. Por ejemplo:

     ..srci > elisp
       > (concat "abc" "def")
       "abcdef"
       > (concat "nuevo "
       ^         (car '("primer elemento" "segundo elemento")))
       "nuevo primer elemento"
       > (concat (car
       ^         '("primer elemento" "segundo elemento")) " modificado")
       "primer elemento modificado"
     < srci..

     Ahora podemos dar sentido a @c{kill-append}: modifica el contenido del
     anillo de la muerte. El anillo de la muerte es una lista, en la que cada
     elemento almacena texto. La función @c{kill-append} usa la función
     @c{kill-new} que a su vez utiliza la función @c{setcar}.

**** La función @c{kill-new}

     La función @c{kill-new} se ve asi:

     ..src > elisp
       (defun kill-new (string &optional replace yank-handler)
         "Hace que STRING sea el último corte en el anillo de la muerte.
       Establece ‘kill-ring-yank-pointer’ para apuntar a el.

       Si ‘interprogram-cut-function’ es no nulo, aplícarlo a STRING.
       El segundo argumento opcional REPLACE no-nulo significa que STRING
        reemplazará el frente del kill ring, en lugar de agregarse a la lista.
       …"
         (if (> (length string) 0)
             (if yank-handler
                 (put-text-property 0 (length string)
                                    'yank-handler yank-handler string))
           (if yank-handler
               (signal 'args-out-of-range
                       (list string "yank-handler specified for empty string"))))
         (if (fboundp 'menu-bar-update-yank-menu)
             (menu-bar-update-yank-menu string (and replace (car kill-ring))))
         (if (and replace kill-ring)
             (setcar kill-ring string)
           (push string kill-ring)
           (if (> (length kill-ring) kill-ring-max)
               (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
         (setq kill-ring-yank-pointer kill-ring)
         (if interprogram-cut-function
             (funcall interprogram-cut-function string (not replace))))
     < src..

     (Observa que la función no es interactiva.)

     Como de costumbre, podemos ver esta función en partes.

     La definición de función tiene un argumento opcional @c{yank-handler},
     que cuando se invoca le dice a la función cómo manejar las propiedades
     añadidas al texto, tales como ‘negrita’ o ‘cursiva’. Nos Saltaremos eso.

     La primer línea de la documentación tiene sentido:

     ..example >
       Hace que STRING sea el último corte en el anillo de la muerte.
     < example..

     Vamos a saltarnos el resto de la documentación por el momento.

     También, vamos a saltar la expresión @c{if} inicial y las líneas de código
     en @c{menu-bar-update-yank-menu}. Las explicaremos mas tarde.

     Las líneas críticas son estas:

     ..src > elisp
         (if (and replace kill-ring)
             ;; entonces
             (setcar kill-ring string)
           ;; de otra forma
         (push string kill-ring)
           (setq kill-ring (cons string kill-ring))
           (if (> (length kill-ring) kill-ring-max)
               ;; evita desbordar el anillo de la muerte
               (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
         (setq kill-ring-yank-pointer kill-ring)
         (if interprogram-cut-function
             (funcall interprogram-cut-function string (not replace))))
     < src..

     La prueba condicional es @c{(and replace kill-ring)}. Esto será verdadero
     cuando se cumplan dos condiciones: el anillo de la muerte tiene algo en el,
     y la variable @c{replace} es verdadera.

     Cuando la función @c{kill-append} establece @c{replace} como verdadero y
     cuando el anillo de la muerte tiene al menos un elemento en el, se ejecuta
     la expresión @c{setcar}.

     ..src > elisp
       (setcar kill-ring string)
     < src..

     La función @c{setcar} realmente cambia el primer elemento de la lista
     @c{kill-ring} al valor de @c{string}. Eso reemplaza el primer
     elemento.

     Por otro lado, si el anillo de la muerte está vacío, o @c(replace) es
     falso, se ejecuta la parte-else de la condición:

     ..src > elisp
       (push string kill-ring)
     < src..

     @c{push} pone su primer argumento dentro del segundo. Es similar a la
     mas antigua

     ..src > elisp
       (setq kill-ring (cons string kill-ring))
     < src..

     o la mas reciente

     ..src > elisp
       (add-to-list kill-ring string)
     < src..

     Cuando es falso, la expresión primero construye una nueva versión del
     anillo de la muerte, añadiendo @c{string} al anillo como un nuevo elemento
     (que es lo que hace @c{push}). Entonces ejecuta una segunda clausula @c{if}.
     Este segundo @c{if} impide que el anillo de la muerte se haga demaciado largo.

     Veamos estas dos expresiones en orden.

     La línea @c{push} de la parte-else asigna el nuevo valor del anillo de la
     muerte a los resultados de agregar la cadena que esta siendo cortada al
     viejo anillo de la muerte.

     Podemos ver cómo funciona esto con un ejemplo.

     Primero,

     ..src > elisp
       (setq lista-de-ejemplo '("aqui hay una clausula" "otra clausula"))
     < src..

     Después de evaluar esta expresión con @k{C-x C-e}, se puede evaluar
     @c{lista-de-ejemplo} y ver que devuelve:

     ..srci > elisp
       > lista-de-ejemplo
       ("aquí hay una claúsula" "otra claúsula")
     < srci..

     Ahora, podemos agregar un nuevo elemento a esta lista evaluando la
     siguiente expresión:

     ..src > elisp
       (push "una tercera cláusula" lista-de-ejemplo)
     < src..

     Cuando evaluamos @c{lista-de-ejemplo}, encontramos que su valor es:

     ..srci > elisp
       > lista-de-ejemplo
       ("una tercera claúsula" "aquí hay una claúsula" "otra claúsula")
     < srci..

     Asi pues, la tercer claúsula se añade a la lista con @c{push}.

     Ahora la segunda parte de la claúsula @c{if}. Esta expresión evita que el
     anillo de la muerte crezca demasiado:

     ..src > elisp
       (if (> (length kill-ring) kill-ring-max)
           (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))
     < src..

     El código comprueba si la longitud del anillo de la muerte es mayor al
     tamaño máximo permitido. Este es el valor de @c{kill-ring-max} (que es 60,
     por defecto). Si el tamaño del anillo de la muerte es demasiado largo,
     entonces este código establece el último elemento del anillo de la muerte a
     @c{nil}. Hace esto usando dos funciones, @c{nthcdr} y @c{setcdr}.

     Vimos @c{setcdr} anteriormente (ver Seccion @l(#@c{setcdr})). Esto asigna
     el @c{cdr} de una lista, asi como @c{setcar} asigna el @c{car} de una
     lista. En este caso, sin embargo, @c{setcdr} no estará configurando el
     @c{cdr} del anillo de la muerte completo; se usa la función @c{nthcdr} para
     asignar el @c{cdr} del último elemento del anillo de la muerte––esto
     significa que puesto que el @c{cdr} del penultimo elemento es el ultimo
     elmento del anillo de la muerte, establecera el último elemento del anillo
     de la muerte.

     La función @c{nthcdr} funciona tomando repetidamente el @c{cdr} de una
     lista––toma el @c{cdr} del @c{cdr} del @c{cdr} …. hace esto @m{N} veces y
     devuelve los resultados. (Consulta la Seccion @l{#@c{nthcdr}}.)

     De este modo, si teniamos una lista de cuatro elementos que supuestamente
     debia tener tres elementos de longitud, podriamos asignar el @c{cdr} del
     elemento siguiente al último a @c{nil}, y asi acortar la lista. (Si se
     asigna el último elemento en algún otro valor distinto a @c{nil}, que se
     podría hacer, entonces no se habría acortado la lista. Consulta la Sección
     @l{#@c{setcdr}}.)

     Puedes ver el acortamiento evaluando las siguientes tres expresiones.
     Primero asigna el valor de @c{arboles} a @c{(arce roble pino abedul)} luego
     establece el @c{cdr} de su segundo @c{cdr} y despues encuentra el valor de
     @c{arboles}.

     ..srci > elisp
       > (setq arboles '(arce roble pino abedul))
       (arce roble pino abedul)
       > (setcdr (nthcdr 2 arboles) nil)
       nil
       > arboles
       (arce roble pino)
     < srci..

     (El valor devuelto por la expresión @c{setcdr} es @c{nil}, ya que en esto
     se establece el @c{cdr}.)

     Para repetir, en @c{kill-new}, la función @c{nthcdr} toma el @c{cdr} un
     número de veces, que es uno menos que el tamaño máximo permitido del anillo
     de la muerte y @c{setcdr} establece el @c{cdr} de este elemento (que será el
     resto de los elementos en el anillo de la muerte) en @c{nil}. Esto evita que
     el anillo de la muerte se alargue demaciado.

     La penultima expresión en la función @c{kill-new} es

     ..src > elisp
       (setq kill-ring-yank-pointer kill-ring)
     < src..

     @c{kill-ring-yank-pointer} es una variable global que se establece
     para ser el @c{kill-ring}.

     Apesar de llamar a @c{kill-ring-yank-pointer} un @'{puntero}, es una
     variable al igual que el anillo de la muerte. Sin embargo, el nombre ha
     sido elegido para ayudar a los humanos a entender cómo se usa la variable.

     Ahora, volviendo a una expresión anterior en el cuerpo de la función:

     ..src > elisp
         (if (fboundp 'menu-bar-update-yank-menu)
              (menu-bar-update-yank-menu string (and replace (car kill-ring))))
     < src..

     Empieza con una expresión @c{if}

     En este caso, la expresión prueba primero si @c{menu-bar-update-yank-menu}
     existe como una función, y si es así, la llama. La función @c{fboundp}
     devuelve verdadero si el símbolo que se prueba tiene una definición de
     función que ‘no es nula’. Si el símbolo de la definición de función fuera
     nulo, recibiríamos un mensaje de error, como lo hicimos cuando se crearon
     errores intencionadamente (Consulta la Seccion @l(#Generar un mensaje de error)).

     La parte-entonces contiene una expresión cuyo primer elemento es la función
     @c{and}.

     La forma especial @c{and} evalúa cada uno de sus argumentos hasta que uno
     de los argumentos devuelve un valor de @c{nil}, en cuyo caso la expresión
     @c{and} devuelve @c{nil}; sin embargo, si ninguno de los argumentos
     devuelve una valor @c{nil}, se devuelve el resultado de la evaluación del
     último argumento. (Puesto que tal valor no es @c{nil}, en Emacs Lisp se
     considera verdadero.) En otras palabras, una expresión @c{and} devuelve un
     valor verdadero solo si todos sus argumentos son verdaderos. (Consulta la Seccion
     @l{#Repaso: Algunas Funciones Más Complejas<>Revisar el segundo búfer
     relacionado}.)

     La expresión determina si el segundo argumento
     @c{menu-bar-update-yank-menu} es verdadero o no.

     @c{menu-bar-update-yank-menu} es una de la funciones que permiten utilizar
     el menu ‘Seleccionar y Pegar’ en el elemento Editar de la barra de menu;
     usando un ratón, puedes ver las distintas piezas de texto que se han
     guardado y seleccionar una pieza para pegar.

     La última expresión en la función @c{kill-new} añade la nueva cadena recien
     copiada a cualquier facilidad existente para copiar y pegar texto entre
     diferentes programas que se ejecutan en un sistema de ventanas. En el
     Sistema de Ventanas X, por ejemplo, la función @c{x-select-text} toma la
     cadena y la almacena en la memoria operada por X. Puede pegar la cadena en
     otro programa, como Xterm.

     La expresión se ve asi:

     ..src > elisp
         (if interprogram-cut-function
             (funcall interprogram-cut-function string (not replace))))
     < src..

     Si @c{interprogram-cut-function} existe, entonces Emacs ejecuta
     @c{funcall}, que a su vez llama a su primer argumento como una función y le
     pasa el resto de argumentos. (Por cierto, hasta donde puedo ver,
     esta expresión @c{if} podría reemplazarse por una expresión @c{and} similar
     a la de la primer parte de la función.)

     No vamos a discutir mas sobre sistemas de ventanas y otros programas, sino
     simplemente indicar que este es un mecanismo que le permite a GNU Emacs
     trabajar bien y fácilmente con otros programas.

     Este código para colocar texto en el anillo de la muerte, ya sea concatenandolo
     con un elemento existente o como un nuevo, nos brinda la habilidad para
     traer texto que ha sido cortado del búfer––los comandos de corte
     @%i(yank). Sin embargo, antes de discutir los comandos de corte, es mejor
     aprender cómo se implementan las listas en un ordenador. Esto pondra de
     manifiesto misterios como el uso del término ‘puntero’. Pero antes de eso,
     nos desviaremos a C.

** Disgresión dentro de C

   La función @c{copy-region-as-kill} (ver Seccion @l{#@c{copy-region-as-kill}})
   utiliza la función @c{filter-buffer-substring}, que a su vez utiliza la función
   @c{delete-and-extract-region}. Eso elimina el contenido de una región y no se
   puede recuperar.

   A diferencia del otro código discutido aquí, la función @c{delete-and-extract-region}
   no está escrita en Emacs Lisp; está escrita en C y es una de las
   primitivas del sistema GNU Emacs. Puesto que es muy simple, hare una breve digresión
   de Lisp y para describirla aquí.

   Al igual que muchas de las otras primitivas Emacs, @c{delete-and-extract-region}
   se escribe como una instancia de una macro C, una macro es una plantilla de
   codigo. La macro completa tiene el siguiente aspecto:

   ..src > c
     DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
            Sdelete_and_extract_region, 2, 2, 0,
            doc: /* Borra el texto entre START y END y lo devuelve.  */)
            (Lisp_Object start, Lisp_Object end)
     {
       validate_region (&start, &end);
       if (XINT (start) == XINT (end))
         return empty_unibyte_string;
       return del_range_1 (XINT (start), XINT (end), 1, 1);
     }
   < src..

   Sin entrar en los detalles del proceso de escritura de la macro, permitame
   señalar que esta macro comienza con la palabra @c{DEFUN}. Se eligio la
   palabra @c{DEFUN} porque el código tiene el mismo propósito que @c{defun} en
   Lisp. (La macro C @c{DEFUN} se define en @f{emacs/src/lisp.h}.)

   La palabra @c{DEFUN} tiene siete partes dentro de los paréntesis:

   - La primera parte es el nombre dado a la función en Lisp,
     @c{delete-and-extract-region}.

   - La segunda parte es el nombre de la función en C,
     @c{Fdelete_and_extract_region}. Por convención, comienza con @'{F}. Puesto
     que C no usa guiones en los nombres, en su lugar se utilizan guiones bajos.

   - La tercera parte es el nombre para la estructura constante C que
     registra información sobre esta función para uso interno. Es el nombre de
     la función en C pero empieza con una @'{S} en lugar de una @'{F}.

   - Las partes cuarta y quinta especifican el número mínimo y máximo de
     argumentos que la función puede tener. Esta función requiere exactamente
     2 argumentos.

   - La sexta parte es casi como el argumento que sigue a la declaración
     @c{interactive} en una función escrita en Lisp: una letra seguida, tal vez,
     por un prompt. La única diferencia con Lisp es cuando se llama a la macro sin
     argumentos. Entonces se escribe un @c{0} (que es una ‘cadena nula’), como
     en esta macro.

     Si fueras a especificar argumentos, se colocarian entre comillas. La macro
     C para @c{goto-char} incluye @c{"NGoto char "} en esta posición se indica
     que la función espera un prefijo sin procesar, en este caso, una localización
     numérica en un búfer, y proporciona un prompt.

   - La séptima parte es una cadena de documentación, igual a la de una función
     escrita en Emacs Lisp. Se escribe como un comentario C. (Cuando se construye
     Emacs, el programa @${lib-src/make-docfile} extrae estos comentarios y los
     usa para crear la documentación “real”.)


   En una macro C, los parámetros formales vienen a continuacion, con una
   declaracion de que tipo de objeto son, seguido por lo que podría llamarse el
   ‘cuerpo’ de la macro. Para @c{delete-and-extract-region} el ‘cuerpo’ se
   compone de las cuatro líneas siguientes:

   ..src > c
     validate_region (&start, &end);
     if (XINT (start) == XINT (end))
       return build_string ("");
     return del_range_1 (XINT (start), XINT (end), 1, 1);
   < src..

   La función @c{validate_region} comprueba si los valores pasados como el
   principio y fin de la región son del tipo apropiado y estan dentro del
   rango. Si las posiciones de inicio y fin son las mismas, entonces
   devuelve una cadena vacía.

   La función @c{del_range_1} borra el texto. Es una función compleja que no
   examinaremos. Actualiza el búfer y hace otras cosas. Sin embargo, vale la
   pena mirar los dos argumentos pasados a @c{del_range}. Estos son @c{XINT
   (start)} y @c{XINT (end)}.

   Por lo que respecta al lenguaje C, @c{start} y @c{end} son dos enteros que
   marcan el principio y el fin de la región a eliminar@n{10}.

   En las primeras versiones de Emacs, estos dos números tenian 32 bits de
   longitud, pero el código está lentamente siendo generalizado para manejar
   otras longitudes. Tres de los bits disponibles son usados para especificar el
   tipo de información; los bits restantes se utilizan como ‘contenido’.

   @c{XINT} es una macro C que extrae el numero relevante desde una colección
   mas larga de bits; los otros tres bits se descartan.

   El comando en @c{delete-and-extract-region} se ve asi:

   ..src > c
     del_range_1 (XINT (start), XINT (end), 1, 1);
   < src..

   Borra la región entre la posición inicial, @c{start}, y la posición final,
   @c{end}.

   Desde el punto de vista de la persona que escribe Lisp, Emacs es muy simple;
   pero oculta en el fondo mucha complejidad para hacer que todo funcione.

** Inicializando una variable con @c{defvar}

   La función @c{copy-region-as-kill} esta escrita en Emacs Lisp. Dos funciones
   dentro de ella, @c{kill-append} y @c{kill-new}, copian una región en un búfer
   y la guardan en una variable llamada @c{kill-ring}. Esta sección describe
   cómo se crea e inicializa la variable @c{kill-ring} usando la forma especial
   @c{defvar}.

   (De nuevo, se señala que el término @c{kill-ring} es un mal nombre. El texto
   que se corta del búfer puede ser traido de vuelta; no es un anillo de cadaveres, sino
   un anillo de texto resucitable.)

   En Emacs Lisp, una variable como @c{kill-ring} se crea y se le da un valor inicial
   usando la forma especial @c{defvar}. El nombre proviene de “definir variable”.

   La forma especial @c{defvar} es similar a @c{setq} en la que se establece el
   valor de una variable. Se diferencia de @c{setq} en dos formas: primero solo
   establece el valor de la variable si la variable no tiene ya un valor. Si la
   variable ya tiene un valor, @c{defvar} no sobreescribe el valor
   existente. Segundo, @c{defvar} tiene una cadena de documentación.

   (Otra forma especial, @c{defcustom}, está diseñada para variables que las
   personas personalizan. Tiene más funcionalidades que @c{defvar}. (Consulta la
   Sección @l{#Especificar variables usando @c{defcustom}}.)

   Se puede ver el valor actual de una variable, cualquier variable, usando la
   función @c{describe-variable}, que normalmente se invoca escribiendo @k{C-h
   v}. Si presionas @k{C-h v} y luego escribes @c{kill-ring} (seguido por
   @k{RET}), veras lo que hay actualmente en tu anillo de la muerte––¡puede
   ser bastante grande! Por el contrario, si no has estado haciendo nada en esta
   sesión en Emacs, excepto leer este documento, es posible no tener nada en
   el. Ademas, se verá la documentación de @c{kill-ring}:

   ..example >
     Documentación:
     Lista de secuencias de texto muerto.
     Ya que el anillo de la muerte se supone que interactua bien con
     el copia-y-pega que ofrecen los sistemas de ventanas, el uso de
     esta variable debería interactuar bien con las funciones
     ‘interprogram-cut-function’ e ‘interprogram-paste-function’.
     Las funciones ‘kill-new’, ‘kill-append’, y ‘current-kill’ deben
     implementar esta interacción; es posible que desee utilizarlas
     en lugar de manipular el anillo de la muerte directamente.
   < example..

   El anillo de la muerte es definido por un @c{defvar} del siguiente modo:

   ..src > elisp
     (defvar kill-ring nil
       "Lista de secuencia de texto muerto.
     …")
   < src..

   En esta definición de variable, a la variable se le da un valor inicial de
   @c{nil}, lo que tiene sentido, ya que si no has guardado nada, no quieres
   nada de vuelta al dar un comando @c{yank}. La cadena de documentación se
   escribe igual que la cadena de documentación de un @c{defun}. Al igual que
   con la cadena de documentacion del defun, la primera linea de la
   documentación deberia ser una frase completa, ya que algunos comandos, como
   @c{apropos}, imprimen solo la primer línea de documentación. Las líneas
   sucesivas no deben indentarse; de lo contrario, se veran extrañas cuando se use
   @k{C-h v} @%c(describe-variable).

*** @c{defvar} y un asterisco

    En el pasado, Emacs usaba la forma especial @c{defvar} tanto para variables
    internas que se esperaba que un usuario cambiara como para las que no se
    esperaban cambios de parte del usuario. Aunque todavía se puede usar
    @c{defvar} para variables personalizadas, por favor, utiliza @c{defcustom} en
    su lugar, ya que esa forma especial proporciona una ruta a los comando de
    personalización. (Consulta la Seccion @l{#Especificar variables usando
    @c{defcustom}}.)

    Cuando se especifica una variable utilizando la forma especial @c{defvar},
    se podría distinguir una variable que un usuario puede querer cambiar de
    las demas escribiendo, @'{*}, en la primera columna de su cadena de
    documentación. Por ejemplo:

    ..src > elisp
      (defvar shell-command-default-error-buffer nil
        "*Nombre de buffer para ‘shell-command’ … salida de error.
      … ")
    < src..

    Podrías (y todavía puedes) usar el comando @c{set-variable} para cambiar
    temporalmente el valor de @c{shell-command-default-error-buffer}. Sin
    embargo, las opciones configuradas usando @c{set-variable} solo se
    establecen durante la duración de tu sesión actual. Los nuevos valores no se
    guardan entre sesiones. Cada vez que Emacs inicia, lee el valor original, a
    menos que cambie el valor dentro de su fichero @f{.emacs}, ya sea configurándolo
    manualmente o utilizando @c{customize}. Consulta la Seccion @l{#Tu Fichero
    @f{.emacs}}.

    Para mí, el mayor uso del comando @c{set-variable} es sugerir variables que
    se podría querer establecer en mi fichero @f{.emacs}. Ahora hay más de 700
    variables, demasiadas para recordarlas fácilmente. Afortunadamente, se puede
    presionar @k{TAB} después de llamar al comando @c{M-x set-variable} para ver
    la lista de variables. (Consulta la Seccion @l{emacs.html#Examining<>Examinando
    y Configurando Variables} en @e(El Manual de GNU Emacs).)

** Repaso

   Aquí hay un breve resumen de algunas funciones introducidas recientemente.

   - @c(car), @c(cdr) ::

     @c{car} devuelve el primer elemento de una lista; @c{cdr} devuelve el
     segundo y los siguientes elementos de una lista.

     Por ejemplo:

     ..srci > elisp
       > (car '(1 2 3 4 5 6 7))
       1
       > (cdr '(1 2 3 4 5 6 7))
       (2 3 4 5 6 7)
     < srci..

   - @c(cons) ::

     @c{cons} construye una lista enlazando su primer argumento a su segundo
     argumento.

     Por ejemplo:

     ..srci > elisp
       > (cons 1 '(2 3 4))
       (1 2 3 4)
     < srci..

   - @c(funcall) ::

     @c{funcall} evalúa su primer argumento como una función. Pasa los
     argumentos restantes a su primer argumento.

   - @c(nthcdr) ::

     Devuelve el resultado de tomar el @c{cdr} ‘n’ veces en una lista. El
     @m(nᵗʰ) @%i(enesimo) @c{cdr}. El ‘resto del resto’, por asi decirlo.

     Por ejemplo:

     ..srci > elisp
       > (nthcdr 3 '(1 2 3 4 5 6 7))
       (4 5 6 7)
     < srci..

   - @c(setcar), @c(setcdr) ::

     @c{setcar} cambia el primer elemento de una lista; @c{setcdr} cambia el
     segundo y los siguientes elementos de una lista.

     Por ejemplo:

     ..srci > elisp
       > (setq triple '(1 2 3))
       > (setcar triple '37)
       > triple
       (37 2 3)
       > (setcdr triple '("foo" "bar"))
       > triple
       (37 "foo" "bar")
     < srci..

   - @c(progn) ::

     Evalúa cada argumento en secuencia y luego devuelve el valor del
     último.

     Por ejemplo:

     ..srci > elisp
       > (progn 1 2 3 4)
       4
     < srci..

   - @c(save-restriction) ::

     Graba cualquier reduccion @%i(narrowing) que esté en efecto en el búfer
     actual, si la hay, y restablece esa reduccion despues de evaluar los
     argumentos.

   - @c(search-forward) ::

     Busca una cadena y, si se encuentra, mueve el punto. De manera similar,
     para una expresión regular utiliza @c{re-search-forward}. (Consulta la Sección
     @l{#Búsqueda de Expresiones Regulares}, para obtener una explicación de los
     patrones y busquedas de expresiones regulares.)

     @c{search-forward} y @c{re-search-forward} toman cuatro argumentos:

     1. La cadena o expresión regular a buscar.

     2. Opcionalmente, el límite de la búsqueda.

     3. Opcionalmente, que hacer si la búsqueda falla, devuelve @c{nil} o un
        mensaje de error.

     4. Opcionalmente, cuántas veces repetir la búsqueda; si es negativa, la
        búsqueda va hacia atrás.

   - @c(kill-region), @c(delete-and-extract-region), @c(copy-region-as-kill) ::

     @c{kill-region} corta el texto entre el punto y la marca del búfer y
     almacena ese texto en el anillo de la muerte, para que puedas recuperarlo
     "tirando" de el.

     @c{copy-region-as-kill} copia el texto entre punto y marca dentro del
     anillo de la muerte. La función no corta ni elimina el texto del búfer.


     @c{delete-and-extract-region} elimina el texto entre el punto y la marca del
     búfer. No puede recuperarse. (Este no es un comando interactivo.)

** Ejercicios de Busqueda

   - Escribe una función interactiva que busque una cadena de texto. Si la
     búsqueda encuentra la cadena, deja el punto después de ella y muestra un
     mensaje que diga “¡Encontrado!”. (No uses @c{search-forward} para el nombre
     de esta función; si lo haces, se sobreescribirá la versión existente de
     @c{search-forward} que viene con Emacs. En su lugar utiliza un nombre como,
     por ejemplo, @c{test-search}.

   - Escribe una función que imprima el tercer elemento del anillo de la muerte
     en el área de eco, si lo hay; si el anillo de la muerte no contiene un
     tercer elemento, imprime un mensaje apropiado.

* Cómo se implementan las listas

  En Lisp, los átomos se registran de manera directa, si la implementación no
  es directa en la práctica, es, sin embargo, directa en teoría. El átomo
  @'c{rosa}, por ejemplo, se graba como las cuatro letras contiguas @'c{r}, @'c{o},
  @'c{s}, @'c{a}. Una lista, por otro lado, se guarda de manera diferente. El
  mecanismo es igualmente simple, pero toma un momento acostumbrarse a la
  idea. Una lista se guarda usando una serie de pares de punteros. En las serie,
  el primer puntero de cada par apunta a un átomo o a otra lista, y el segundo
  puntero de cada par apunta al siguiente par, o al símbolo @c{nil}, que marca
  el final de la lista.

  Un puntero por sí mismo es simplemente la dirección electrónica de lo que
  se apunta. Por lo tanto, una lista se guarda como una serie de direcciones
  electrónicas.

  Por ejemplo, la lista @c{(rosa violeta tulipan)} tiene tres elementos,
  @'c{rosa}, @'c{violeta}, y @'c{tulipan}. En el ordenador, la dirección
  electrónica de @'c{rosa} se registra en un segmento de memoria del ordenador
  junto con la dirección que da la dirección electrónica de donde se encuentra
  el átomo @'c{violeta}; y esta dirección (la que dice donde se localiza
  @'c{violeta}) se guarda junto con una dirección que dice donde se localiza la
  dirección para el átomo @'c{tulipan}.

  Esto parece más complicado de lo que es y es más fácil visto en un
  diagrama:

  ..art >
     ___ ___      ___ ___      ___ ___
    |___|___|--> |___|___|--> |___|___|--> nil
      |            |            |
      |            |            |
      ---> rosa    ---> violeta ---> tulipan
  < art..

  En el diagrama, cada caja representa una palabra de la memoria del ordenador
  que contiene un objeto Lisp, normalmente en forma de una dirección de
  memoria. Las cajas, es decir, las direcciones, están en pares. Cada flecha
  apunta a la dirección de un átomo u otro par de direcciones. La primer caja es
  la dirección electrónica de @'c{rosa} y la flecha apunta a @'c{rosa}; la segunda
  caja es la dirección del siguiente par de cajas, la primera parte de las
  cuales que es la dirección de @'c{violeta} y la segunda parte es la dirección
  del siguiente par. La última caja apunta al símbolo @c{nil}, que marca el fin
  de la lista.

  Cuando una variable se establece en una lista con una función como @c{setq},
  almacena la dirección de la primera caja en la variable. Asi pues, la
  evaluación de la expresión

  ..src > elisp
    (setq ramo '(rosa violeta tulipan))
  < src..

  crea una situación como esta:

  ..art >
    ramo
      |
      |     ___ ___      ___ ___      ___ ___
       --> |___|___|--> |___|___|--> |___|___|--> nil
             |            |            |
             |            |            |
              --> rosa     --> violeta   --> tulipan
  < art..

  En este ejemplo, el símbolo @c{ramo} contiene la dirección del primer par de
  cajas.

  Esta misma lista puede ser ilustrada en un tipo diferente de notación de
  cajas como este:

  ..art >
    ramo
      |
      |    --------------       ----------------       --------------------
      |   | car   | cdr  |     | car     | cdr  |     | car         | cdr  |
       -->| rosa  |   o------->| violeta |   o------->| tulipan     | nil  |
          |       |      |     |         |      |     |             |      |
           --------------       ----------------       --------------------
  < art..

  (Los símbolos consisten en más de un par de direcciones, pero la estructura de
  un símbolo esta formado por direcciones. En efecto, el símbolo @c{ramo}
  consiste de un grupo de cajas-de-direcciones, una de las cuales es la
  dirección de la palabra impresa @'{ramo}, la segunda es la dirección de una
  definición de función adjunta al símbolo, si la hubiera, una tercera parte la
  cual es la dirección del primer par de cajas-de-direccion para la lista
  @c{(rosa violeta tulipan)}, y así sucesivamente. Aquí mostraremos que la
  tercera caja de direcciónes del símbolo apunta al primer par de
  cajas-de-direccion de la lista.)

  Si un símbolo se asigna al @c{cdr} de una lista, la lista en sí no cambia; el
  símbolo simplemente tiene una dirección mas abajo en la lista. (En la jerga,
  @c{car} y @c{cdr} son ‘no destructivos’.) De este modo, la evaluacion de la
  siguiente expresión

  ..src > elisp
    (setq flores (cdr ramo))
  < src..

  produce esto:

  ..art >
    ramo        flores
      |              |
      |     ___ ___  |     ___ ___      ___ ___
       --> |   |   |  --> |   |   |    |   |   |
           |___|___|----> |___|___|--> |___|___|--> nil
             |              |            |
             |              |            |
              --> rosa       --> violeta  --> tulipan
  < art..

  El valor de @c{flores} es @c{(violeta tulipan)}, es decir, el símbolo
  @c{flores} contiene la dirección del par de cajas-de-direcciones, la primera
  de las cuales contiene la dirección de @c{violeta}, y la segunda contiene la
  dirección de @c{tulipan}.

  Un par de cajas-de-direcciones se denomina una @:{cons cell} o @:{par de
  puntos}. Consulta la Seccion @l{elisp.html#Cons Cell Type<>Cons Cell y Tipos
  de Lista} en @e(El Manual de Referencia de Emacs Lisp), y @l{elisp.html#Dotted
  Pair Notation<>Notación de Par Punteado} en @e(El Manual de Referencia de
  GNU Emacs Lisp), para más información acerca las cons cells y los pares punteados.

  La función @c{cons} añade un nuevo par de direcciones al frente de una serie
  de direcciones como la que se muestra a continuacion. Por ejemplo, evaluar la
  expresión

  ..src > elisp
    (setq ramo (cons 'lila ramo))
  < src..

  produce:

  ..art >
    ramo                       flores
      |                             |
      |     ___ ___        ___ ___  |     ___ ___       ___ ___
       --> |   |   |      |   |   |  --> |   |   |     |   |   |
           |___|___|----> |___|___|----> |___|___|---->|___|___|--> nil
             |              |              |             |
             |              |              |             |
              --> lila      --> rosa       --> violeta    --> tulipan
  < art..

  Sin embargo, esto no cambia el valor del símbolo @c{flores}, como puedes ver
  evaluando lo siguiente,

  ..src > elisp
    (eq (cdr (cdr ramo)) flores)
  < src..

  que devuelve @c{t} por verdadero.

  Hasta que se reinicia, @c{flores} todavía tiene el valor @c{(violeta
  tulipan)}; es decir, tiene la dirección de la cons cell cuya primer dirección
  es @c{violeta}. Ademas, esto no altera ninguna de las cons cell
  preexistentes; todas ellas todavía están allí.

  De este modo, en Lisp, para obtener el @c{cdr} de una lista, solo tienes que
  obtener la dirección de la siguiente cons cell de la serie; al obtener el
  @c{car} de una lista, se obtiene la dirección del primer elemento de la lista;
  al agregar @%c(cons) un nuevo elemento en una lista, se añade una nueva cons
  cell al frente de la lista. ¡Esto es todo lo que hay! ¡La estructura
  subyacente de Lisp es brillantemente simple!

  ¿Y a que se refiere la última dirección en una serie de cons cell? Es la
  direccion de la lista vacía, @c{nil}.

  En resumen, cuando una variable Lisp se establece a un valor, se proporciona
  la dirección de la lista a la que se refiere la variable.

** Símbolos como una caja con cajones

   En una sección anterior, sugeri que se podría imaginar un símbolo como una
   caja con cajones. La definición de función se coloca en un cajón, el valor en
   otro, etcetera. Lo que se pone en el cajón que contiene el valor puede
   cambiarse sin afectar el contenido del cajón que contiene la definicion de
   función, y viceversa.

   En realidad, lo que se pone en la caja es la dirección del valor o definición
   de función. Es como si encontraras un viejo cofre en el ático, y en uno de
   sus compartimentos hallaras un mapa que te indica donde yace el tesoro
   enterrado.

   (Además de su nombre, la definición del símbolo, y un valor de variable, un
   símbolo tiene un ‘cajón’ para una @:{lista de propiedades} que puede utilizar
   para registrar otra información. Las listas de propiedades no se discuten
   aquí; ver la seccion @l{elisp.html#Property Lists<>Listas de Propiedades} en
   @e{El Manual de Referencia de Emacs Lisp}.)

   Aquí hay una representación imaginaria:

   ..art >
         Caja de Cajones            Contenidos de los Cajones

         __   o0O0o   __
       /                 \
      ---------------------
     |    direcciones al   |            [asignar a]
     | nombre del simbolo  |            ramo
     |                     |
     +---------------------+
     |  direcciones a la   |
     |   definición del    |            [nada]
     |    simbolo          |
     +---------------------+
     |    direcciones al   |            [asignar a]
     |   valor de variable |            (rosa violeta tulipan)
     |                     |
     +---------------------+
     |    direcciones a la |
     |lista de propiedades |            [no descrito aquí]
     |                     |
     +---------------------+
     |/                   \|
   < art..

** Ejercicio

   Asignar @c{flores} a @c{violeta} y @c{tulipan}. Asignar dos flores más en
   esta lista y asignarla a @c{mas-flores}. Asignar el @c{car} de @c{flores} a un
   pez. ¿Qué lista contiene ahora @c{mas-flores}?

* Traer de regreso el texto

  Siempre que cortas texto de un búfer con un comando ‘kill’, puede traerse de
  vuelta con un comando ‘yank’. El texto cortado del búfer es puesto en el
  anillo de la muerte y los comandos yank insertan el contenido apropiado del
  anillo de la muerte en un búfer (no necesariamente el búfer original).

  Un simple comando @k{C-y} @%c(yank) inserta el primer elemento del anillo de
  la muerte en el búfer actual. Si el comando @k{C-y} es seguido
  inmediatamente por @k{M-y}, el primer elemento se reemplaza por el segundo
  elemento. Los sucesivos comandos @k{M-y} reemplazan el segundo elemento con el
  tercer, cuarto, o quinto elemento, y así sucesivamente. Cuando se alcanza el
  último elemento del anillo de la muerte, se reemplaza por el primer elemento y
  el ciclo se repite. (Por la tanto, el anillo de la muerte se llama un ‘anillo’
  en lugar de solo una ‘lista’. Sin embargo, la estructura de datos real que
  contiene el texto es una lista. Consulta la Seccion @l{#Apéndice B: Manejando el
  anillo de la muerte}, para los detalles de cómo se maneja la lista como un
  anillo.)

** Resumen del anillo de la muerte

   El anillo de la muerte es una lista de cadenas de texto. Asi es como luce:

   ..src > elisp
     ("algún texto" "un texto diferente" "aún más texto")
   < src..

   Si este fuera el contenido de mi anillo de la muerte y pulsara @k{C-y},
   la cadena de caracteres que dice @'c{algún texto} seria insertada en este
   búfer donde se encuentra mi cursor.

   El comando @c{yank} también se utiliza para duplicar texto copiándolo. El
   texto copiado no se corta del búfer, sino que se coloca una copia del
   mismo en el anillo de la muerte y se inserta trayendolo de vuelta.

   Se utilizan tres funciones para devolver el texto del anillo de la muerte:
   @c{yank}, que normalmente se asocia a @k{C-y}; @c{yank-pop}, que normalmente
   se asocia a @k{M-y}; y @c{rotate-yank-pointer}, que se utiliza por las otras
   dos funciones.

   Estas funciones se refieren al anillo de la muerte a través de una variable
   llamada @c{kill-ring-yank-pointer}. De hecho, el codigo de inserción para
   ambas funciones @c{yank} y @c{yank-pop} es:

   ..src > elisp
     (insert (car kill-ring-yank-pointer))
   < src..

   (Bueno, ya no más. En GNU Emacs 22, la función ha sido reemplazada por
   @c{insert-for-yank} que llama repetidamente a @c{insert-for-yank-1} para cada
   segmento a @c{yank-handler}. A su vez, @c{insert-for-yank-1} elimina las
   propiedades del texto insertado de acuerdo a @c{yank-excluded-properties}. De
   otro modo, seria como @c{insert}. Nosotros pegaremos con un @c{insert} plano
   puesto que es mas fácil de comprender.)

   Para empezar a comprender cómo funcionan @c{yank} y @c{yank-pop}, primero hay
   que mirar la variable @c{kill-ring-yank-pointer}.

** La variable @c{kill-ring-yank-pointer}

   @c{kill-ring-yank-pointer} es una variable, de la misma forma que
   @c{kill-ring} es una variable. Apunta a alguna cosa al estar ligada al
   valor de lo que apunta, como cualquier otra variable Lisp.

   De este modo, si el valor del anillo de la muerte es:

   ..src > elisp
     ("algún texto" "un texto diferente" "aún más texto")
   < src..

   y @c{kill-ring-yank-pointer} apunta a la segunda oracion, el valor de
   @c{kill-ring-yank-pointer} es:

   ..src > elisp
     ("un texto diferente" "aún más texto")
   < src..

   Como se explico en el capítulo anterior (Consulta la Seccion @l{#Cómo se
   implementan las listas}), el ordenador no guarda dos copias diferentes del
   texto apuntadas tanto por @c{kill-ring} como por @c{kill-ring-yank-pointer}.
   Las palabras “un texto diferente” y “aún más texto” no están duplicadas. En
   su lugar, las dos variables apuntan a las mismas piezas de texto. Aquí hay un
   diagrama:

   ..art >
     kill-ring     kill-ring-yank-pointer
         |               |
         |      ___ ___  |     ___ ___      ___ ___
          ---> |   |   |  --> |   |   |    |   |   |
               |___|___|----> |___|___|--> |___|___|--> nil
                 |              |            |
                 |              |            |
                 |              |             --> "aún más texto"
                 |              |
                 |               --> "un texto diferente"
                 |
                  --> "algún texto"
   < art..

   Tanto la variable @c{kill-ring} como @c{kill-ring-yank-pointer} son
   punteros. Pero el anillo de la muerte en sí suele describirse como si fuera
   realmente de lo que esta compuesto. Se habla de @c{kill-ring} como si fuera la
   lista en lugar de ser un puntero a la lista. Por el contrario, se dice que
   @c{kill-ring-yank-pointer} apunta a una lista.

   Estas dos formas de hablar sobre la misma cosa suenan confusas al principio
   pero tienen sentido tras reflexionar. El anillo de la muerte se piensa
   generalmente como la estructura completa de datos que contiene la información
   de lo que se ha cortado reciéntemente de los búfers de Emacs. Por otra parte,
   @c{kill-ring-yank-pointer}, sirve para indicar––es decir, para ‘apuntar
   a’––esa parte del anillo de la muerte de la cual se inserta el primer
   elemento (el @c{car}).

** Ejercicios con @c{yank} y @c{nthcdr}

   - Usando @k{C-h v} @%c(describe-variable), mira en el valor de tu anillo de
     la muerte. Añade varios elementos a tu anillo de la muerte; mira su valor
     de nuevo. Usando @k{M-y} @%c{yank-pop}, muevete alrededor del anillo de la
     muerte. ¿Cuántos elementos habia en tu anillo de la muerte? Encuentra el
     valor de @c{kill-ring-max}. ¿Estaba lleno tu anillo de la muerte, o podrías
     haber guardado más bloques de texto dentro en el?

   - Usando @c{nthcrd} y @c{car}, construye una serie de expresiones para
     devolver el primer, segundo, tercer y cuarto elemento de una lista.

* Bucles y recursión

  Emacs Lisp tiene dos formas principales para hacer que una expresión, o una
  serie de expresiones, se evaluen repetidamente: una usa un bucle @c{while},
  y la otra @:{recursión}.

  La repetición puede ser muy valiosa. Por ejemplo, para avanzar cuatro
  oraciones, solo necesitas escribir un programa que avance una oracion y luego
  repetir el proceso cuatro veces. Ya que un ordenador no se aburre ni se cansa,
  tal acción repetitiva no tiene los efectos nocivos (como un monton de errores)
  que puede tener en los humanos.

  La mayoria de personas escriben sus funciones de Emacs Lisp usando bucles
  @c{while} y sus parientes; pero se puede usar la recursión, que provee un una
  manera muy poderosa de pensar para resolver problemas@n{11}.

** @c{while}

   La forma especial @c{while} prueba si el valor devuelto tras evaluar su
   primer argumento es verdadero o falso. Esto es parecido a lo que el
   intérprete Lisp hace con un @c{if}; sin embargo, lo que el interprete hace
   despues es diferente.

   En una expresión @c{while}, si el valor devuelto al evaluar el primer
   argumento es falso, el intérprete Lisp omite el resto de la expresión (el
   @:{cuerpo} de la expresión) y no la evalúa. Sin embargo, si el valor es
   verdadero, el intérprete evalúa el cuerpo de la expresión y luego prueba
   nuevamente si el primer argumento de @c{while} es verdadero o falso. Si el
   valor devuelto al evaluar el primer argumento vuelve a ser verdadero, el
   intérprete Lisp vuelve a evaluar el cuerpo de la expresión.

   La plantilla para una expresión @c{while} luce así:

   ..src > elisp
     (while prueba-verdadero-o-falso
       cuerpo…)
   < src..

   Siempre que la evaluacion de prueba-verdadero-o-falso en la expresion
   @c{while} devuelva un valor verdadero, el cuerpo sera evaluado repetidamente.
   Este proceso se llama bucle porque el intérprete Lisp repite lo mismo una y
   otra vez, como un avión haciendo un bucle. Cuando el resultado de evaluar
   prueba-verdadero-o-falso es falso, el intérprete no evalúa el resto de la
   expresión @c{while} y ‘sale del bucle’.

   Claramente, si el valor devuelto evaluando el primer argumento de @c{while}
   es siempre cierto, el cuerpo siguiente será evaluado una y otra vez … y otra
   vez … por siempre. Por el contrario, si el valor devuelto nunca es verdadero,
   las expresiones en el cuerpo nunca serán evaluadas. El arte de escribir un
   bucle @c{while} consiste en elegir un mecanismo tal que la
   prueba-verdadero-o-falso devuelva verdadero solo el número de veces que
   requiere evaluar las expresiones subsiguientes, y luego hacer que la prueba
   devuelva falso.

   El valor devuelto al evaluar un @c{while} es el valor de
   prueba-verdadero-o-falso. Una consecuencia interesante de esto es que un
   bucle @c{while} que se evalúa sin errores devolverá @c{nil} o falso
   independientemente de si ha hecho el bucle 1 o 100 veces o ninguna. ¿Una
   expresión @c{while} que se evalúa con exito nunca devuelve un valor
   verdadero! Lo que esto significa es que @c{while} siempre se evalua por sus
   efectos secundarios, es decir, las consecuencias de evaluar las expresiones
   dentro del cuerpo del bucle. Esto tiene sentido. No es el mero acto del bucle
   lo que se desea, sino las consecuencias de lo que ocurre cuando las
   expresiones en el bucle se evaluan repetidamente.

*** Un bucle @c{while} y una lista

    Un forma común para controlar un bucle @c{while} es probar si una lista
    tiene algun elemento. Si es asi, el bucle se repite; pero si no, la
    repetición finaliza. Como esta es una tecnica importante, crearemos un
    ejemplo breve para ilustrarla.

    Un manera sencilla de comprobar si una lista tiene elementos es evaluar la
    lista: si no tiene elementos, se trata de una lista vacía y devuelve la
    lista vacía, @c{()}, que es un sinónimo de @c{nil} o falso. Por otro lado,
    una lista con elementos devolverá estos elementos cuando se evalúe. Ya que
    Emacs Lisp considera como verdadero cualquier valor que no sea @c{nil}, una
    lista que devuelve elementos probara verdadero en un bucle @c{while}.

    Por ejemplo, se puede asignar la variable @c{lista-vacia} a @c{nil} para
    evaluar la siguiente expresión @c{setq}:

    ..src > elisp
      (setq lista-vacia ())
    < src..

    Después de evaluar la expresión @c{setq}, se puede evaluar la variable
    @c{lista-vacia} de la manera habitual, colocando el cursor después del
    símbolo y escribiendo @k{C-x C-e}; aparecerá @c{nil} en tu área de eco:

    ..src > elisp
      lista-vacia
    < src..

    Por otro lado, si se asigna una variable como una lista con elementos, la
    lista aparecerá cuando se evalúe la variable, como se puede ver al evaluar
    las dos expresiones siguientes:

    ..src > elisp
      (setq animales '(gacela jirafa leon tigre))

      animales
    < src..

    De este modo, para crear un bucle @c{while} que pruebe si hay algun elemento
    en la lista @c{animales}, la primera parte del bucle se escribira así:

    ..src > elisp
      (while animales
             …
    < src..

    Cuando @c{while} prueba su primer argumento, la evaluacion de la variable
    @c{animales} devuelve una lista. Mientras la lista tenga elementos, el
    @c{while} considera que el resultado de la prueba es verdadero; pero cuando
    la lista esta vacía, se considera que el resultado de la prueba es falso.

    Para prevenir que el bucle @c{while} se ejecute para siempre, es necesario
    proporcionar algún mecanismo para vaciar la lista. Una técnica usada con
    frecuencia es tener una de las expresiones en el cuerpo de @c{while} que
    asigne el valor del @c(cdr) de la lista a la lista. Cada vez que se evalua
    la función @c{cdr}, la lista se va reduciendo, hasta que finalmente solo
    queda la lista vacía. En este punto, la prueba del bucle @c{while} devolverá
    falso, y al mismo tiempo los argumentos ya no se evaluarán.

    Por ejemplo, la lista de animales asociada a la variable @c{animales} puede
    asignarse a el @c{cdr} de la lista original con la siguiente expresión:

    ..src > elisp
      (setq animales (cdr animales))
    < src..

    Si has evaluado las expresiones anteriores y luego evaluas esta expresión,
    veras aparecer @c{(jirafa leon tigre)} en el área de eco. Si evalúas la
    expresión de nuevo, aparecera @c{(leon tigre)}. Si la evalúas de nuevo una y
    otra vez, veras @c{(tigre)} y despues la lista vacía, mostrada como @c{nil}.

    Una plantilla para un bucle @c{while} usa la función @c{cdr} repetidamente
    para hacer que la prueba-verdadero-o-falso eventualmente se evalue a falso
    como se muesta a continuacion:

    ..src > elisp
      (while prueba-si-la-lista-esta-vacia
        cuerpo…
        establece-lista-al-cdr-de-la-lista)
    < src..

    Esto prueba y uso de @c{cdr} puede colocarse en una funcion a la que se pase
    una lista e imprima cada elemento de esta en una línea propia.

*** Un ejemplo: @c{imprimir-elementos-de-la-lista}

    La función @c{imprimir-elementos-de-la-lista} ilustra un bucle @c{while}
    con una lista.

    La función requiere varias líneas para su salida. Si estás leyendo esto en
    una instancia reciente de GNU Emacs, puedes evaluarlo de la forma habitual.

    Si estas usando una versión antigua de Emacs, es necesario copiar las
    expresiones necesarias en el búfer @f{*scratch*} y evaluarlas allí. Esto se
    debe a que el área de eco solo tenía una línea en las versiones antiguas.

    Puedes copiar las expresiones marcando el principio de la región con
    @k{C-SPC} @%c{set-mark-command}, moviendo el cursor al final de la región y
    luego copiar la región usando @k{M-w} (@c{kill-ring-save}, que llama a
    @c{copy-region-as-kill} y proporciona la realimentación visual). En el búfer
    @f{*scratch*}, puedes copiar las expresiones con @k{C-y} @%c{yank}.

    Después de copiar las expresiones al búfer @f{*scratch*}, evalúa cada
    expresión en orden. Asegúrate de evaluar la última expresión,
    @c{(imprimir-elementos-de-la-lista animales)}, presionando @k{C-u C-x C-e},
    es decir, pasando un argumento a @c{eval-last-sexp}. Esto hara que el
    resultado de la evaluación se imprima en el búfer @f{*scratch*} en lugar de
    imprimirse en el área de eco. (De lo contrario, veras algo como esto en tu
    área de eco: @c{^Jgacela^J^Jjirafa^J^Jleon^J^Jtigre^Jnil}, en la que cada
    @'{^J} seria una ‘nueva línea’.)

    En una instancia de GNU Emacs reciente, podras evaluar estas expresiones
    directamente, y el área de eco crecerá para mostrar los resultados.

    ..src > elisp
      (setq animales '(gacela jirafa leon tigre))

      (defun imprimir-elementos-de-la-lista (list)
        "Imprime cada elemento de LIST en una línea."
        (while list
          (print (car list))
          (setq list (cdr list))))

      (imprimir-elementos-de-la-lista animales)
    < src..

    Cuando evalúes las tres expresiones en secuencia, verás esto:

    ..example >
      gacela

      jirafa

      leon

      tigre
      nil
    < example..

    Cada elemento de la lista se imprime en una línea propia (que es lo que hace
    la función @c{print}) y luego se imprime el valor devuelto por la función.
    Como la última expresión de la función es el bucle @c{while}, y como los
    bucles @c{while} siempre devuelven @c{nil}, se imprime un @c{nil} después
    del último elemento de la lista.

*** Un bucle con un contador incremental

    Un bucle no es útil a menos que pare cuando debe. Ademas de controlar un
    bucle con una lista, una forma comun de detener un bucle es escribir el
    primer argumento como una prueba que devuelve falso cuando el número
    correcto de repeticiones esta completo. Esto significa que el bucle debe
    tener un contador––una expresión que cuenta cuántas veces el bucle se repite
    a sí mismo.

    La prueba para un bucle con un contador incremental puede ser una expresión
    como @c{(< contador numero-deseado)} que devuelve @c{t} para verdadero si el
    valor de @c{contador} es menor que el @c{numero-deseado} de repeticiones y
    @c{nil} para falso si el valor de @c{contador} es igual o mayor al
    @c{numero-deseado}. La expresión que incrementa el contador puede ser un
    simple @c{setq} como @c{(setq contador (1+ contador))}, donde @c{1+} es una
    función nativa de Emacs Lisp que añade 1 a su argumento. (La expresión
    @c{(1+ contador)} tiene el mismo resultado que @c{(+ contador 1)}, pero es
    mas facil de leer para un humano.)

    La plantilla para un bucle @c{while} controlado por un contador que se
    incrementa se ve asi:

    ..src > elisp
      asignar-un-valor-inicial-al-contador
      (while (< contador numero-deseado)         ; prueba-verdadero-o-falso
        cuerpo…
        (setq contador (1+ contador)))           ; incremento
    < src..

    Ten en cuenta que se necesita asignar el valor inicial de @c{contador}; por
    lo general se asigna en 1.

**** Ejemplo con contador incremental

     Supón que estás jugando en la playa y decides crear un triángulo de
     guijarros, poniendo uno en la primera fila, dos en la segunda fila, tres en
     la tercera fila y así sucesivamente:

     ..example >
          •
         • •
        • • •
       • • • •
     < example..

     (Hace 2500 años, Pitágoras y otros desarrollaron los principios de la
     teoría de números al considerar preguntas como esta.)

     Supón que quieres saber cuántos guijarros necesitarás para hacer un
     triángulo con 7 filas

     Claramente, lo que necesitas hacer es sumar los números de 1 a 7. Hay dos
     maneras de hacer esto; se puede comenzar con el numero más pequeño, uno, y
     sumar la lista en secuencia, 1, 2, 3, 4 y así sucesivamente; o empezar con
     el número más grande y sumar la lista hacia abajo: 7, 6, 5, 4 y así
     sucesivamente. Debido a que ambos mecanismos ilustran formas comunes de escribir
     el bucle @c{while}, crearemos dos ejemplos, uno contando hacia arriba y el
     otro contando hacia abajo. En este primer ejemplo, empezaremos con 1 y
     sumaremos 2, 3, 4, etc.

     Si quieres sumar toda una lista de números, el camino más fácil de hacerlo
     es sumar todos los números a la vez. Sin embargo, si no se sabe de antemano
     cuántos números tendrá la lista, o si se requiere estar preparado para una
     lista muy larga, entonces se necesita diseñar la suma de manera que lo que
     haga sea repetir un proceso simple muchas veces en vez de hacer un proceso
     más complejo una solo vez.

     Por ejemplo, en lugar de sumar todos los guijaros a la vez, lo que se puede
     hacer es sumar el número de guijarros en la primera fila, 1, al número de
     la segunda fila, 2, y entonces añadir el total de estas dos filas a la
     tercera fila, 3. Luego se puede sumar el número en la cuarta fila, 4, al
     total de las primeras tres filas; y así sucesivamente.

     La característica crítica del proceso es que cada acción repetitiva sea
     simple. En este caso, en cada paso se suman solo dos números, el número de
     guijarros en la fila y el total ya encontrado. Este proceso de sumar dos
     números se repite una y otra vez hasta que la última fila ha sido añadida
     al total de todas las filas precedentes. En un bucle más complejo la acción
     repetitiva podría no ser tan sencilla, pero será mas simple que hacerlo
     todo de una sola vez.

**** Las partes de la definición de función

     El análisis anterior nos da los huesos de nuestra definición de
     función: primero, necesitaremos una variable que podemos llamar
     @c{total} que será el número total de guijarros. Este será el valor
     devuelto por la función.

     En segundo lugar, sabemos que la función requerirá un argumento: este
     argumento será el número total de filas del triángulo. Puede llamarse
     @c{numero-de-filas}.

     Finalmente, necesitamos una variable para usar como contador. Podriamos
     llamar a esta variable @c{contador}, pero un mejor nombre es
     @c{numero-de-fila}. Esto se debe a que lo que hace el contador en esta
     función es contar filas, y un programa debería escribirse para ser lo mas
     comprensible posible.

     Cuando el intérprete Lisp comienza a evaluar las expresiones de la función,
     el valor de @c{total} debe ponerse a cero, ya que no hemos sumado nada al
     mismo. Luego la función debe sumar el número de guijarros en la primera
     fila al total, y luego sumar el número de guijarros en la segunda al total,
     y luego sumar el número de guijarros en la tercera fila al total, y así
     sucesivamente, hasta que no queden más filas por sumar.

     Tanto @c{total} como @c{numero-de-fila} se usan solo dentro de la función,
     por lo que pueden ser declarados como variables locales con @c{let} dando
     sus valores iniciales. Evidentemente, el valor inicial para total
     sera 0. El valor inicial de @c{numero-de-fila} sera 1, ya que comenzaremos
     con la primer fila. Esto significa que la declaracion @c{let} se vera asi:

     ..src > elisp
       (let ((total 0)
             (numero-de-fila 1))
         cuerpo…)
     < src..

     Después de declarar y asignar las variables internas, podemos comenzar el
     bucle @c{while}. La expresión que sirve como prueba deberia devolver un
     valor de @c{t} para verdadero siempre que el @c{numero-de-fila} sea menor o
     igual al @c{numero-de-filas}. (Si la prueba devuelve verdadero solo si el
     número de fila es menor que el número de filas en el triángulo, la última
     fila nunca se sumara al total; por lo tanto, el número de fila tiene que
     ser menor o igual al número de filas.)

     Lisp proporciona la función @c{<=} que devuelve verdadero si el valor de su
     primer argumento es menor o igual al valor de su segundo argumento y falso
     de lo contrario. Así que la expresión que el @c{while} evaluará como su prueba
     deveria verse asi:

     ..src > elisp
       (<= numero-de-fila numero-de-filas)
     < src..

     El número total de guijarros se puede encontrar sumando repetidamente el
     número de guijarros en una fila al total ya encontrado. Puesto que el
     número de guijarros en la fila es igual al número de la fila, el total
     puede encontrarse añadiendo el número de filas al total. (Claramente, en
     una situación más compleja, el número de guijarros en la fila podría estar
     relacionado con el número de la fila de una manera más complicada; si este
     fuera el caso, el número de la fila sería reemplazado por la expresión
     apropiada.)

     ..src > elisp
       (setq total (+ total numero-de-fila))
     < src..

     Lo que esto hace es asignar el nuevo valor de @c{total} para que sea igual
     a la suma del número de guijarros en la fila al total anterior.

     Después de establecer el valor de @c{total}, se deben establecer las
     condiciones para la siguiente repetición del bucle, si hay alguna. Esto se
     hace incrementando el valor de la variable @c{numero-de-fila}, que sirve
     como contador. Después de incrementar la variable @c{numero-de-fila}, la
     prueba-verdodero-o-falso al principio del bucle @c{while} prueba si su
     valor aun es menor o igual al valor del @c{numero-de-filas} y, si lo es,
     suma el nuevo valor de la variable @c{numero-de-fila} al @c{total} de la
     repetición previa.

     La función nativa @c{1+} en Emacs Lisp añade 1 a un número, por lo que la
     variable @c{numero-de-fila} puede incrementarse con esta expresión:

     ..src > elisp
       (setq numero-de-fila (1+ numero-de-fila))
     < src..

**** Juntando la definición de función

     Hemos creado las partes para la definición de la función; ahora necesitamos
     juntarlas.

     Primero, el contenido de la expresión @c{while}:

     ..src > elisp
       (while (<= numero-de-fila numero-de-filas)    ; prueva-verdadero-o-falso
         (setq total (+ total numero-de-fila))
         (setq numero-de-fila (1+ numero-de-fila)))  ; incremento
     < src..

     Junto con la expresión @c{let} de la varlist, casi completan el cuerpo de
     la definición de función. Sin embargo, se requiere un ultimo elemento, cuya
     necesidad es algo sutil.

     El toque final es colocar la variable @c{total} en una línea por sí misma
     después de la expresión @c{while}. De lo contrario, el valor devuelto por
     la función completa sera el valor de la última expresión en evaluarse
     dentro del cuerpo del @c{let}, y este es el valor devuelto por el @c{while}
     que es siempre @c{nil}.

     Esto puede no ser evidente a primera vista. Casi parece como si la
     expresión de incremento fuera la última expresión de la función
     completa. Pero esa expresión es parte del cuerpo del @c{while}; es el
     último elemento de la lista que empieza con el símbolo @c{while}. Ademas,
     todo el bucle @c{while} es una lista dentro del cuerpo del @c{let}.

     En el esquema, la función tendra este aspecto:

     ..src > elisp
       (defun nombre-de-la-funcion (lista-de-argumentos)
         "documentacion…"
         (let (varlist)
           (while (prueba-verdadero-o-falso)
             cuerpo-de-while… )
           … ))                    ; aqui necesita la expresión final.
     < src..

     El resultado de evaluar el @c{let} es lo que va a ser devuelto por
     @c{defun} ya que @c{let} no está embebido dentro de ninguna lista que la
     contenga, excepto por el @c{defun} como un todo. Sin embargo, si el
     @c{while} es el último elemento de la expresión @c{let}, la función siempre
     devolverá @c{nil}. ¡Esto no es lo que queremos! En vez de eso, queremos el
     valor de la variable @c{total}. Esto se devuelve simplemente colocando el
     símbolo como el último elemento de la lista que comienza con @c{let}. Se
     evalúa después de evaluar los elementos precedentes, lo que significa que
     se evaluó después de que se le ha asignado el valor correcto para el total.

     Puede ser mas fácil ver esto imprimiendo la lista iniciada por @c{let} en
     una línea. Este formato hace evidente que las expresiones @c{varlist} y
     @c{while} son el segundo y tercer elementos de la lista iniciado por
     @c{let}, y @c{total} es el último elemento:

     ..src > elisp
       (let (varlist) (while (prueba-verdadero-o-falso) cuerpo-de-while… ) total)
     < src..

     Poniendo todo junto, la definición de la función @c{triangulo} se ve asi:

     ..src > elisp
       (defun triangulo (numero-de-filas)  ; Versión con
                                           ;   contador de incremento.
         "Suma el número de guijarros en un triángulo.
       La primera fila tiene un guijarro, la segunda fila dos guijarros,
       la tercera fila tres guijarros, y así sucesivamente.
       El argumento es NUMERO-DE-FILAS."
         (let ((total 0)
               (numero-de-fila 1))
           (while (<= numero-de-fila numero-de-filas)
             (setq total (+ total numero-de-fila))
             (setq numero-de-fila (1+ numero-de-fila)))
           total))
     < src..

     Después de haber instalado @c{triangulo} al evaluar la función, puedes
     probarla. Aquí hay dos ejemplos:

     ..src > elisp
       (triangulo 4)

       (triangulo 7)
     < src..

     La suma de los primeros cuatro números es 10 y la suma de los primeros
     siete números es 28.

*** Bucle con un contador decreciente

    Otra manera común de escribir un bucle @c{while} es con una prueba que
    determine si un contador es mayor que cero. Mientras el contador sea mayor
    que cero, el bucle se repite. Pero cuando el contador es igual o menor que
    cero, el bucle se detiene. Para que esto funcione, el contador tiene que
    empezar por encima de cero y luego hacerse mas y mas pequeño mediante una forma
    que se evalue repetidamente.

    La prueba será una expresión como @c{(> contador 0)} que devuelve @c{t} para
    verdadero si el valor del @c{contador} es mayor que cero, y @c{nil} para
    falso si el valor del @c{contador} es igual a o menor que cero. La expresión
    que hace que el número menor sea cada vez mas pequeño puede ser un simple
    @c{setq} como @c{(setq contador (1- contador)}, donde @c{1-} es una función
    nativa en Emacs Lisp que resta 1 de su argumento.

    La plantilla para un bucle @c{while} decreciente se ve así:

    ..src > elisp
      (while (> contador 0)                   ; prueba-verdadero-o-falso
        cuerpo…
        (setq contador (1- contador)))        ; decremento
    < src..

**** Ejemplo con contador decreciente

     Para ilustrar un bucle con un contador decreciente, reescribiremos la
     función @c{triangulo} para que el contador disminuya a cero.

     Esto es lo inverso de la versión anterior de la función. En este caso, para
     saber cuantos guijarros se necesitan para crear un triángulo con 3 filas,
     se suma el número de guijarros en la tercera fila, 3, al numero en la fila
     anterior, 2, y luego se suman el total de esas dos filas a la fila que lo
     precede, que es 1.

     Del mismo modo, para encontrar el número de guijarros en un triángulo con 7
     filas, se suma el número de guijarros en la septima fila, 7, al número en la
     fila anterior, que es 6, y luego se suma el total de estas dos filas a la
     fila que las precede, que es 5, y así sucesivamente. Como en el ejemplo
     anterior, cada suma solo implica sumar dos números, el total de las filas ya
     sumadas y el número de guijarros en la fila que se suma al total. Este
     proceso de sumar dos números se repite una y otra vez hasta que no haya más
     guijarros que agregar.

     Sabemos con cuántos guijarros empezar: el número de guijarros en la última
     fila es igual al número de filas. Si el triángulo tiene siete filas, el
     número de guijarros en la última fila es 7. Del mismo modo, sabemos cuántos
     guijarros hay en la fila anterior: uno menos que el número en la fila
     actual.

**** Las partes de la definición de función

     Empezamos con tres variables: el número total de filas en el triángulo; el
     número de guijarros en una fila; y el número total de guijarros, que es lo
     que queremos calcular. Estas variables pueden llamarse @c{numero-de-filas},
     @c{numero-de-guijarros-en-fila}, y @c{total}, respectivamente.

     Tanto @c{total} como @c{numero-de-guijarros-en-fila} se usan solo dentro de
     la función y se declaran con @c{let}. El valor inicial de @c{total} deberia
     ser cero. Sin embargo, el valor inicial de @c{numero-de-guijarros-en-fila}
     deberia ser igual al número de filas en el triángulo, ya que la suma
     comenzara con la fila más larga.

     Esto significa que el principio de la expresión @c{let} se verá así:

     ..src > elisp
       (let ((total 0)
             (numero-de-guijarros-en-fila numero-de-filas))
         cuerpo…)
     < src..

     El número total de guijarros se puede encontrar sumando repetidamente
     el número de guijarros en una fila al total ya encontrado, es decir,
     evaluando repetidamente la siguiente expresión:

     ..src > elisp
       (setq total (+ total numero-de-guijarros-en-fila))
     < src..

     Después de sumar @c{numero-de-guijarros-en-fila} al @c{total}, el
     @c{numero-de-guijarros-en-fila} debe decrecer por uno, ya que la siguiente
     vez que el bucle se repita, la fila anterior se sumara al total.

     El número de guijarros en una fila anterior es uno menos que el número de
     guijarros en la fila actual, por lo que se utilizara la función nativa
     @c{1-} de Emacs para calcular el número de guijarros de la fila
     anterior. Esto se puede hacer con la siguiente expresión:

     ..src > elisp
       (setq numero-de-guijarros-en-fila
             (1- numero-de-guijarros-en-fila))
     < src..

     Finalmente, sabemos que el bucle @c{while} deberia detenerse cuando no
     halla guijarros en una fila. Así que la prueba en el bucle @c{while} es
     simple:

     ..src > elisp
       (while (> numero-de-guijarros-en-fila 0)
     < src..

**** Juntando la definición de función

     Podemos juntar estas expresiones para crear una definición de función que
     funcione. Sin embargo, al examinarlas, encontraremos que una de las
     variables locales ¡es innecesaria!

     La definición de función tiene este aspeto:

     ..src > elisp
       ;;; Primer version decreciente.
       (defun triangulo (numero-de-filas)
         "Suma el número de guijarros en un triángulo."
         (let ((total 0)
               (numero-de-guijarros-en-fila numero-de-filas))
           (while (> numero-de-guijarros-en-fila 0)
             (setq total (+ total numero-de-guijarros-en-fila))
             (setq numero-de-guijarros-en-fila
                   (1- numero-de-guijarros-en-fila)))
           total))
     < src..

     Como esta escrita, esta función funciona.

     Sin embargo, no se necesita @c{numero-de-guijarros-en-fila}.

     Cuando se evalua la función @c{triangulo}, el símbolo @c{numero-de-filas} se
     vinculara a un número, dandole un valor inicial. Ese número puede ser
     modificado en el cuerpo de la función como si fuera una variable local, sin
     temor a que tal cambio afecte el valor de la variable fuera de la
     función. Esta es una característica muy útil de Lisp; significa que la
     variable @c{numero-de-filas} se puede utilizar en cualquier lugar de la
     función donde se utilice @c{numero-de-guijarros-en-fila}.

     Aquí hay una segunda versión de la función escrita un poco más
     limpiamente:

     ..src > elisp
       (defun triangulo (numero)                ; Segunda versión.
         "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO."
         (let ((total 0))
           (while (> numero 0)
             (setq total (+ total numero))
             (setq numero (1- numero)))
           total))
     < src..

     En resumen, un bucle @c{while} escrito apropiadamente constará de tres
     partes:

     1. Una prueba que devuelva falso después de que el bucle se ha repetido el
        número de veces correcto.

     2. Una expresión cuya evaluación repetida devuelva el valor deseado.

     3. Una expresión para cambiar el valor pasado a la prueba-verdadero-o-falso
        para que esta devuelva falso después de que el bucle se haya repetido el
        numero de veces correcto.

** Ahorra tu tiempo: @c{dolist} y @c{dotimes}

   Además de @c{while}, tanto @c{dolist} como @c{dotimes} permiten hacer
   bucles. Algunas veces estos son mas rápidos de escribir que el bucle @c{while}
   equivalente. Ambas son macros Lisp. (Consulta la Seccion
   @l{elisp.html#Macros<>Macros} en @e(El Manual de Referencia GNU Emacs Lisp).)

   @c{dolist} funciona como un bucle @c{while} con ‘@c{cdr}s que acortan la
   lista’: @c{dolist} acorta automáticamente la lista con cada bucle––toma el @c{cdr} de
   la lista––y liga el @c{car} de cada versión mas corta al primero de sus
   argumentos.

   @c{dotimes} repite el bucle un número específico de veces: tu especificas el
   número.

*** La macro @c{dolist}

    Supón, por ejemplo, que quieres invertir una lista, para que “primero”,
    “segundo”, “tercero” se convierta en “tercero”, “segundo”, “primero”.

    En la práctica, usarías la función @c{reverse}, como aqui:

    ..src > elisp
      (setq animales '(gacela jirafa leon tigre))

      (reverse animales)
    < src..

    A continuacion se muestra como se podría invertir la lista usando un bucle
    @c{while}:

    ..src > elisp
      (setq animales '(gacela jirafa leon tigre))

      (defun invertir-lista-con-while (lista)
        "Usando while, invierte el orden de LISTA."
        (let (valor)  ; asegura que la lista comienza vacía
          (while lista
            (setq valor (cons (car lista) valor))
            (setq lista (cdr lista)))
          valor))

      (invertir-lista-con-while animales)
    < src..

    Y aquí se ve cómo puedes usar la macro @c{dolist}:

    ..src > elisp
      (setq animales '(gacela jirafa leon tigre))

      (defun invertir-lista-con-dolist (lista)
        "Usando dolist, invierte el orden de LISTA."
        (let (valor)  ; asegura que la lista empieza vacía
          (dolist (elemento lista valor)
            (setq valor (cons elemento valor)))))

      (invertir-lista-con-dolist animales)
    < src..

    Puedes colocar el cursor después del parentesis de cierre de
    cada expresión y pulsar @k{C-x C-e}; en cualquier caso, deberias ver

    ..src > elisp
      (tigre leon jirafa gacela)
    < src..

    en el área de eco.

    Para este ejemplo, la función @c{reverse} obviamente es la mejor opcion. El
    bucle @c{while} es como nuestro primer ejemplo (Consulta la Seccion @l{#Un bucle
    @c{while} y una lista}). @c{while} comprueba si la lista tiene elementos; si
    es así, construye una nueva lista añadiendo el primer elemento de la lista a
    la lista existente (que en la primer iteración del bucle es @c{nil}). Puesto
    que el segundo elemento se asigna delante del primero, y el tercero delante
    del segundo, la lista se invierte.

    En la expresión que usa un bucle @c{while}, la expresión @c{(setq lista (cdr
    lista))} acorta la lista, por lo que el bucle @c{while} termina
    deteniendose. Además, se proporciona la expresión @c{cons} con un nuevo
    primer elemento creando una nueva lista en cada repetición del bucle.

    La expresión @c{dolist} hace lo mismo que la expresión @c{while}, excepto
    que la macro @c{dolist} hace algo del trabajo que tienes que hacer cuando se
    escribe una expresión @c{while}.

    Como un bucle @c{while}, @c{dolist} hace un bucle. Lo que es diferente es
    que @%c(dolist) acorta automáticamente la lista con cada repeticion––con
    ‘@c{cdr}s que reducen la lista’ por su cuenta––y asocia automáticamente el
    @c{car} de cada versión acortada de la lista al primero de sus argumentos.

    En el ejemplo, el @c{car} de cada versión reducida de la lista se vincula al
    símbolo @'{elemento}, la lista en sí se llama @'{lista}, y el valor devuelto
    se llama @'{valor}. El resto de la expresión @c{dolist} es el cuerpo.

    La expresión @c{dolist} asocia el @c{car} de cada versión reducida de la
    lista a @c{elemento} y luego evalúa el cuerpo de la expresión y repite
    el bucle. El resultado es devuelto en @c{valor}.

*** La macro @c{dotimes}

    La macro @c{dotimes} es similar a @c{dolist}, excepto que el bucle se
    repite un número específico de veces.

    Al primer argumento de @c{dotimes} se le asignan los números 0, 1, 2 y así
    sucesivamente cada iteracion, y se devuelve el valor del tercer argumento.
    Se necesita proveer el valor del segundo argumento, que es el numero de
    veces que la macro se repite.

    Por ejemplo, lo siguiente asocia al primer argumento @c(numero) los números
    de 0 en adelante, pero no incluye, el número 3, y luego construye una lista
    de los tres números. (El primer número es 0, el segundo es 1, y el tercero es
    2; esto hace un total de tres, comenzando con cero como el primer número.)

    ..srci > elisp
      > (let (valor)      ; de otro modo, "valor" es una variable vacia
      ^   (dotimes (numero 3 valor)
      ^     (setq valor (cons numero valor))))
      (2 1 0)
    < srci..

    @c{dotimes} devuelve @c{valor}, así que la forma de usar @c{dotimes} es
    operar sobre alguna expresión @c(numero) un numero de veces y luego devolver el
    resultado, como una lista o un átomo.

    Aquí hay un ejemplo de un @c{defun} que usa @c{dotimes} para sumar el número
    de guijarros en un triángulo.

    ..src > elisp
      (defun triangulo-utilizando-dotimes (numero-de-filas)
        "Usando dotimes, suma el número de guijarros en un triángulo."
      (let ((total 0))  ; de otro modo total es una variable vacía
        (dotimes (numero numero-de-filas total)
          (setq total (+ total (1+ numero))))))

      (triangulo-utilizando-dotimes 4)
    < src..

** Recursividad

   Una función recursiva contiene código que indica al intérprete Lisp que llame
   a un programa que se ejecuta exactamente como el, pero con argumentos
   ligeramente diferentes. El código funciona exactamente igual porque tiene el
   mismo nombre. Sin embargo, aunque el programa tenga el mismo nombre, no es la
   misma entidad. Eso diferente. En la jerga, se dice es una ‘instancia’
   diferente.

   Eventualmente, si el programa se escribe correctamente, los ‘argumentos
   ligeramente diferentes’ llegan a ser suficientemente diferentes de los
   primeros argumentos para que la instancia final se detenga.

*** Construyendo robots: Extendiendo la metáfora

    Algunas veces es útil pensar en un programa en ejecución como un robot que
    hace un trabajo. Al hacer su trabajo, una función recursiva llama a un
    segundo robot para que le ayude. El segundo robot es idéntico al primero en
    todos los sentidos, excepto que el segundo robot ayuda al primero y ha
    recibido argumentos diferentes al primero.

    En una función recursiva, el segundo robot puede llamar a un tercero; y el
    tercero puede llamar a un cuarto, y así sucesivamente. Cada uno de ellos es
    una entidad diferente; pero todos son clones.

    Dado que cada robot tiene instrucciones ligeramente diferentes––los
    argumentos difieren de un robot a otro––el último robot deberia saber cuando
    detenerse.

    Expandamos la metáfora en la que un programa de ordenador es un robot.

    Una definición de función proporciona los planos de un robot. Cuando se
    instala una definición de función, que es, cuando se evalúa una forma
    especial @c{defun}, se instala el equipo necesario para construir robots. Es
    como si estuvieras en una fábrica, construyendo una línea de montaje. Los
    robots con el mismo nombre se construyen segun los mismos planos. Así que
    tienen, por asi decirlo, el mismo ‘número de modelo’, pero un ‘número de
    serie’ diferente.

    A menudo decimos que una función recursiva ‘se llama así misma’. Lo que
    queremos decir es que las instrucciones en una función recursiva hacen que
    el intérprete Lisp ejecute una función diferente que tiene el mismo nombre y
    hace el mismo trabajo que la primera, pero con argumentos diferentes.

    Es importante que los argumentos difieran de una instancia a la siguiente;
    de otro modo, el proceso nunca se detendra.

*** Las partes de una definición recursiva

    Una función recursiva típicamente contiene una expresión condicional que
    tiene tres partes:

    1. Una prueva-verdadero-o-falso que determina si la función se vuelve a llamar,
       aquí se llamara @:{prueba-hazlo-de-nuevo}.

    2. El nombre de la función. Cuando este nombre se llama, se crea una nueva
       instancia de la función––un nuevo robot, por asi decirlo––y se le dice qué
       hacer.

    3. Una expresión que devuelve un valor diferente cada vez que se llama a la
       función, aquí se llamara @:{expresion-del-siguiente-paso}.
       Consecuentemente, el argumento (o argumentos) pasados a la nueva
       instancia de la función será diferente del argumento (o argumentos)
       pasados a la instancia previa. Esto hace que la expresión condicional, la
       @:{prueba-hazlo-de-nuevo}, devuelva falso después del número correcto de
       repeticiones.


    Las funciones recursivas pueden ser mucho más simples que cualquier otro
    tipo de funcion. De hecho, cuando las personas comienzan a usarlas, con
    frecuencia parecen tan misteriosamente simples que resultan incomprensibles.
    Al igual que montar en bicicleta, leer la definicion de una función
    recursiva requiere una cierta habilidad, es dificil al principio, pero
    después parece facil.

    Hay varios patrones recursivos diferentes. Un patrón muy simple se ve asi:

    ..src > elisp
      (defun nombre-de-funcion-recursiva (lista-de-argumentos)
        "documentation…"
        (if prueba-hazlo-de-nuevo
          cuerpo…
          (nombre-de-funcion-recursiva expresion-del-siguiente-paso)))
    < src..

    Cada vez que se evalua una función recursiva, se crea una nueva instancia y
    se le dice qué hacer. Los argumentos indican a la instancia qué hacer.

    Un argumento es ligado al valor de la expresion-del-siguiente-paso. Cada
    instancia se ejecuta con un valor de la expresion-del-siguiente-paso
    diferente.

    El valor en la expresion-del-siguiente-paso se utiliza en la
    prueba-hazlo-de-nuevo.

    El valor devuelto por la expresion-del-siguiente-paso se pasa a la nueva
    instancia de la función, que lo evalúa para determinar si continua o se
    detiene. La expresion-del-siguiente-paso está diseñada para que la
    prueba-hazlo-de-nuevo devuelva falso cuando la función ya no deba repetirse.

    La prueba-hazlo-de-nuevo a veces se denomina @:{condición de parada}, ya que
    detiene las repeticiones cuando la prueba falla.

*** Recursividad con una lista

    El ejemplo de un bucle @c{while} que imprimia los elementos de una lista
    de números puede escribirse recursivamente. Aquí está el código,
    incluyendo una expresión para asignar el valor de la variable
    @c{animales} a una lista.

    Si estás leyendo esto dentro de Emacs, puedes evaluar la expresión
    directamente. De lo contrario, debes copiar el ejemplo al búfer
    @f{*scratch*} y evalúar cada expresión alli. Utiliza @k{C-u C-x C-e} para
    evaluar la expresión @c{(imprimir-elementos-recursivamente animales)} de
    manera que se imprima el resultado en el búfer; de otro modo el intérprete
    Lisp intentara comprimir los resultados en la unica línea del área de eco.

    También, coloca el  cursor inmediatamente después del último paréntesis
    de cierre de la función @c{imprimir-elementos-recursivamente}, antes del
    comentario. De lo contrario, el intérprete Lisp intentará evaluar el
    comentario.

    ..src > elisp
      (setq animales '(gacela jirafa leon tigre))

      (defun imprimir-elementos-recursivamente (lista)
        "Imprime cada elemento de LISTA en una línea propia.
      Usa recursión."
        (when lista                               ; prueba-hazlo-de-nuevo
              (print (car lista))                 ; cuerpo
              (imprimir-elementos-recursivamente  ; llamada recursiva
               (cdr lista))))                     ; expresion-del-siguiente-paso

      (imprimir-elementos-recursivamente animales)
    < src..

    La función @c{imprimir-elementos-recursivamente} primero prueba si hay algun
    contenido en la lista; si lo hay, la función imprime el primer elemento de
    la lista, el @c{car} de la lista. Entonces la función se ‘invoca a sí
    misma’, pero se da como argumento, no la lista completa, sino el segundo
    y subsiguientes elementos de esta, es decir, el @c{cdr} de la lista.

    Dicho de otro modo, si la lista no está vacía, la función invoca otra
    instancia de código que es similar al código inicial, pero es un hilo
    de ejecución diferente, con argumentos diferentes o los de la primera instancia.

    Dicho de otra manera mas, si la lista no está vacía, el primer robot ensambla
    un segundo robot y le dice qué hacer; el segundo robot es un individuo
    diferente del primero, pero es del mismo modelo.

    Cuando se produce la segunda evaluación, se evalua la expresión @c{when} y
    si es verdadera, imprime el primer elemento de la lista que recibe como
    argumento (que es el segundo elemento de la lista original). A continuacion
    la función ‘se llama a sí misma’ (la segunda vez) con el @c{cdr} del @c{cdr}
    de la lista original.

    Ten en cuenta que aunque decimos que la función ‘se llama a sí misma’, lo
    que queremos decir es que el intérprete Lisp ensambla e instruye una nueva
    instancia del programa. La nueva instancia es un clon del primero, pero es
    un individuo separado.

    Cada vez que la función ‘se invoca a sí misma’, se invoca con una versión
    mas corta de la lista original. Crea una nueva instancia que funciona en una
    lista mas corta.

    Eventualmente, la función se invoca a sí misma con una lista vacía. Crea una
    nueva instancia cuyo argumento es @c{nil}. La expresión condicional prueba
    el valor de @c{lista}. Ya que el valor de la @c{lista} es @c{nil}, la
    expresión @c{when} prueba falso por lo que la parte-then no se evalua. La
    función como un todo entonces devuelve @c{nil}.

    Cuando se evalúa la expresión @c{(imprimir-elementos-recursivamente animales)} en
    el búfer @f{*scratch*}, se ve este resultado:

    ..example >
      gacela

      jirafa

      leon

      tigre
      nil
    < example..

*** Recursión en lugar de un contador

    La función @c{triangulo} descrita en una sección anterior tambien se puede
    escribir recursivamente. Se vera así:

    ..src > elisp
      (defun triangulo-recursivo (numero)
        "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO.
      Usa recursion."
        (if (= numero 1)                    ; prueba-hazlo-de-nuevo
            1                               ; parte-then
          (+ numero                         ; parte-else
             (triangulo-recursivo           ; llamada recursiva
              (1- numero)))))               ; expresion-del-siguiente-paso

      (triangulo-recursivo 7)
    < src..

    Puedes instalar esta función evaluandola y luego probarla evaluando
    @c{(triangulo-recursivo 7)}. (Recuerda colocar el cursor inmediatamente
    después del último paréntesis de la definición de la función, antes del
    comentario.) La función se evalúa a 28.

    Para comprender cómo funciona esta función, hay que considerar qué ocurre en
    varios casos cuando la función pasa 1, 2, 3, o 4 como el valor de su
    argumento.

    Primero, ¿que sucede si el valor del argumento es 1?

    La función tiene una expresión @c{if} después de la cadena de
    documentación. Prueba si el valor de @c{numero} es igual a 1; si es
    así, Emacs evalúa la parte-then de la expresión @c{if}, que devuelve el
    número 1 como el valor de la función. (Un triángulo con una fila tiene un
    guijarro dentro.)

    Supón, sin embargo, que el valor del argumento es 2. En este caso, Emacs
    evalúa la parte-else de la expresión @c{if}.

    La parte-else consiste en una suma, la llamada recursiva a
    @c{triangulo-recursivo} y una acción de decremento; y se ve así:

    ..src > elisp
      (+ numero (triangulo-recursivo (1- numero)))
    < src..

    Cuando Emacs evalúa esta expresión, la expresión interna se evalua
    primero; luego las otras partes en secuencia. Aquí están los pasos en
    detalle:

    - Paso 1 Evalúar la expresión mas interna.

      La expresión mas interna es @c{(1- numero)} por lo que Emacs decrementa el valor
      de @c{numero} de 2 a 1.

    - Paso 2 Evalúar la función @c{triangulo-recursivo}.

      El intérprete Lisp crea una instancia individual de @c{triangulo-recursivo}.
      No importa que esta función este contenida dentro de sí misma. Emacs pasa
      el resultado del Paso 1 como el argumento usado por esta instancia de la
      función @c{triangulo-recursivo}

      En este caso, Emacs evalúa @c{triangulo-recursivo} con un argumento
      de 1. Esto significa que esta evaluación de @c{triangulo-recursivo}
      devuelve 1.

    - Paso 3 Evalúar el valor de @c{numero}.

      La variable @c{numero} es el segundo elemento de la lista que empieza
      con @c{+}; su valor es 2.

    - Paso 4 Evalúar la expresión @c{+}.

      La expresión @c{+} recibe dos argumentos, el primero viene de la
      evaluación del @c{numero} (Paso 3) y el segundo de la evaluación de
      @c{triangulo-recursivo} (Paso 2).

      El resultado de la operacion es la suma de 2 + 1, y se devuelve el número
      3, que es correcto. Un triángulo con dos filas tiene tres guijarros.

**** Un argumento de 3 o 4

     Supón que @c{triangulo-recursivo} se llama con un argumento de 3.

     - Paso 1 Evalúa la prueba-hazlo-de-nuevo.

       La expresión @c{if} se evalúa primero. Esto es la prueba-hazlo-de-nuevo y
       devuelve falso, así que se evalua la parte-else de la expresión
       @c{if}. (Ten en cuenta que en este ejemplo, la prueba-hazlo-de-nuevo
       hace que la función se llame a sí misma cuando la prueba es falsa, no
       cuando es verdadera.)

     - Paso 2 Evalúar la expresión mas interna de la parte-else.

       Se evalua la expresión mas interna de la parte-else, que decrementa 3
       a 2. Esta es la expresion-del-siguiente-paso.

     - Paso 3 Evalúar la función @c{triangulo-recursivo}.

       El número 2 se pasa a la función @c{triangulo-recursivo}.

       Nosotros ya sabemos lo que ocurre cuando Emacs evalúa
       @c{triangulo-recursivo} con un argumento de 2. Después de pasar a través de
       la secuencia de acciones descritas anteriormente, devuelve un valor
       de 3. Así que eso es lo que ocurrirá aquí.

     - Paso 4 Evalúar la suma.

       3 será pasado como argumento a la suma y se sumara al número con el que
       se ha llamado a la función, que es 3.


     El valor devuelto por la función en su conjunto será 6.

     Ahora que sabemos qué ocurrirá cuando se llame a @c{triangulo-recursivo}
     con un argumento de 3, es evidente lo que ocurrirá si se llama con un
     argumento de 4:

     ..tab >
       En la llamada recursiva, la evaluación de

       ..src > elisp
         (triangulo-recursivo (1- 4))
       < src..

       devolvera el valor de evaluar

       ..src > elisp
         (triangulo-recursivo 3)
       < src..

       que es 6 y este valor se sumara a 4 mediante la suma en la tercera
       línea.
     < tab..


     El valor devuelto por la función en su conjunto será 10.

     Cada vez que se evalua @c{triangulo-recursivo}, se evalua una
     versión de sí misma––una instancia diferente en sí––con un argumento
     mas pequeño, hasta que el argumento es lo suficientemente pequeño para que
     no se evalue a si misma.

     Ten en cuenta que este particular diseño de una función recursiva
     requiere que las operaciones se pospongan.

     Antes de que @c{(triangulo-recursivo 7)} pueda calcular su respuesta, debe
     llamar a @c{(triangulo-recursivo 6)}; y antes de que
     @c{(triangulo-recursivo 6)} pueda calcular su respuesta debe llamar a
     @c{(triangulo-recursivo 5)}; y así sucesivamente. Es decir, el cálculo
     que hace @c{(triangulo-recursivo 7)} debe ser pospuesto hasta que
     @c{(triangulo-recursivo 6)} haga su cálculo; y @c{(triangulo-recursivo 6)}
     debe posponerse hasta que @c{(triangulo-recursivo 5)} se complete; y así
     sucesivamente.

     Si se piensa que cada una de estas instancias de @c{triangulo-recursivo}
     son robots diferentes, el primer robot debe esperar al segundo para
     completar su trabajo, que debe esperar hasta que el tercero se complete, y
     así sucesivamente.

     Hay una forma de evitar este tipo de espera, que se discutirá en la Seccion
     @l{#Recursividad sin aplazamiento}.

*** Ejemplo de recursión usando @c{cond}

    La versión de @c{triangulo-recursivo} descrita anteriormente se escribió con la
    forma especial @c{if}. También se puede escribir usando otra forma
    especial llamada @c{cond}. El nombre de la forma especial @c{cond} es una
    abreviación de la palabra @'{conditional} @%i(condicional).

    Aunque la forma especial @c{cond} no se usa tan a menudo en las fuentes
    de Emacs como @c{if}, se usa con bastante frecuencia para justificar su
    explicacion.

    La plantilla de una expresión @c{cond} se ve asi:

    ..src > elisp
      (cond
       cuerpo…)
    < src..

    donde el @c{cuerpo} es una serie de listas.

    Escrito de forma más completa, la plantilla se ve asi:

    ..src > elisp
      (cond
       (primera-prueba-verdadero-o-falso primera-consequencia)
       (segunda-prueba-verdadero-o-falso segunda-consequencia)
       (tercera-prueba-verdadero-o-falso tercera-consequencia)
        …)
    < src..

    Cuando el intérprete Lisp evalúa la expresión @c{cond}, evalúa el primer
    elemento (el @c{car} o prueba-verdadero-o-falso) de la primer expresión en
    una serie de expresiones dentro del cuerpo del @c{cond}.

    Si la prueba-verdadero-o-falso devuelve @c{nil} el resto de esa expresión,
    la consecuencia; se descarta y se evalua la prueba-verdadero-o-falso de la
    siguiente expresión.  Cuando se encuentra una expresión cuya
    prueba-verdadero-o-falso devuelve un valor que no es @c{nil}, se evalua la
    consecuencia de esa expresión. La consecuencia puede ser una o más expresiones. Si
    la consecuencia consiste de más de una expresión, las expresiones se evaluan en
    secuencia y se devuelve el valor de la última. Si la expresión no tiene
    consecuencia, se devuelve el valor de la prueba-verdadero-o-falso.

    Si ninguna de las pruebas prueba-verdadero-o-falso es verdadera, la
    expresión @c{cond} devuelve @c{nil}.

    Asi se ve la función @c{triangle}, usando @c{cond}:

    ..src > elisp
      (defun triangulo-usando-cond (numero)
        (cond ((<= numero 0) 0)
              ((= numero 1) 1)
              ((> numero 1)
               (+ numero (triangulo-usando-cond (1- numero))))))
    < src..

    En este ejemplo, @c{cond} devuelve 0 si el número es menor o igual a 0,
    devuelve 1 si el número es 1 y evalúa @c{(+ numero (triangulo-usando-cond
    (1- numero)))} si el número es mayor a 1.

*** Patrones recursivos

    Aquí hay tres patrones recursivos comunes. Cada uno implica una lista. La
    recursión no necesita involucrar listas, pero Lisp esta diseñado para listas
    y esto proporciona una idea de sus capacidades primarias.

**** Patrón recursivo: @e{every}

     En el patrón recursivo @c{every}, se desarrolla una acción en cada
     elemento de una lista.

     El patrón básico es:

     - Si una lista esta vacía, devuelve @c{nil}.

     - Si no, actua al principio de la lista (el @c{car} de la lista)

       + a través de una llamada recursiva por la función en el resto (el
         @c{cdr}) de la lista,

       + y, opcionalmente, combina el elemento sobre el que actúa, usando
         @c{cons}, con los resultados de actuar sobre el resto.


     Aquí está el ejemplo:

     ..src > elisp
       (defun cuadrar-cada-uno (lista-de-numeros)
         "El cuadrado de cada elemento en LISTA DE NUMEROS, recursivamente."
         (if (not lista-de-numeros)          ; prueba-hazlo-de-nuevo
             nil
           (cons
            (* (car lista-de-numeros) (car lista-de-numeros))
            (cuadrar-cada-uno (cdr lista-de-numeros))))) ; expresion-del-siguiente-paso
     < src..

     ..srci > elisp
       > (cuadrar-cada-uno '(1 2 3))
       (1 4 9)
     < srci..

     Si @c{lista-de-numeros} está vacía, no hay que hacer nada. Pero si tiene
     contenido, se construye una lista combinando el cuadrado del primer
     número en la lista con el resultado de la llamada recursiva.

     (El ejemplo sigue el patrón exactamente: se devuelve @c{nil} si la lista
     de números esta vacía. En la práctica, se escribiría el condicional para que
     lleve a cabo la acción cuando la lista de números no este vacía.)

     La función @c{imprimir-elementos-recursivamente} (Ver Sección @l{#Recursividad
     con una Lista}) es otro ejemplo de un patrón @c{every}, excepto que en este
     caso, en vez de juntar los resultados usando @c{cons}, se imprime
     cada elemento de salida.

     La función @c{imprimir-elementos-recursivamente} se ve asi:

     ..src > elisp
       (setq animales '(gacela jirafa leon tigre))

       (defun imprimir-elementos-recursivamente (lista)
         "Imprime cada elemento de LISTA en una línea propia.
       Usa recursión."
         (when lista                               ; prueba-hazlo-de-nuevo
               (print (car lista))                 ; cuerpo
               (imprimir-elementos-recursivamente  ; llamada recursiva
                (cdr lista))))                     ; expresion-del-siguiente-paso

       (imprimir-elementos-recursivamente animales)
     < src..


     El patrón para @c{imprimir-elementos-recursivamente} es:

     - Cuando la lista está vacía, no hacer nada.

     - Pero cuando la lista tiene al menos un elemento,

       - actúar al principio de la lista (el @c{car} de la lista),

       - y hacer una llamada recursiva en el resto (el @c{cdr} de la lista).

**** Patrón recursivo: @e{accumulate}

     Otro patrón recursivo se llama patrón @c{accumulate}. En el patrón
     recursivo @c{accumulate}, se realiza una acción en cada elemento de una
     lista y el resultado de esta acción se acumula con los resultados de
     realizar la acción en los otros elementos.

     Esto es muy parecido al patron ‘every’ usando @c{cons}, excepto que
     no se utiliza @c{cons}, sino algun otro combinador.

     El patrón es:

     - Si una lista está vacía, devuelve cero u otra constante.

     - De lo contrario, actúa al principio de la lista (el @c{car} de la lista),

       - y combina el elemento actual, utilizando @c{+} o alguna otra
         función de combinación, con

       - una llamada recursiva a la función con el resto (el @c{cdr}) de la
         lista.


     Aquí hay un ejemplo:

     ..src > elisp
       (defun sumar-elementos (lista-de-numeros)
         "Suma los elementos de LISTA-DE-NUMEROS."
         (if (not lista-de-numeros)
             0
           (+ (car lista-de-numeros) (sumar-elementos (cdr lista-de-numeros)))))
     < src..

     ..srci > elisp
       > (sumar-elementos '(1 2 3 4))
       10
     < srci..

     Consulta la Seccion @l{#Creando una lista de ficheros}, para un ejemplo del
     patrón accumulate.

**** Patrón recursivo: @e{keep}

     Un tercer patrón se llama el patrón @c{keep}. En el patrón recursivo
     @c{keep}, se prueba cada elemento de una lista; se actúa sobre el elemento
     y los resultados se conservan solo si el elemento cumple un criterio.

     De nuevo, esto es muy parecido al patrón ‘every’, excepto que el elemento
     se descarta a menos que cumpla un criterio.

     El patrón tiene tres partes:

     - Si una lista esta vacía, devuelve @c{nil}.

     - De lo contrario, si el inicio de la lista (el @c{car}) pasa una prueba

       - actuar sobre ese elemento y combinarlo, utilizando @c{cons} con

       - una llamada recursiva a la función con el resto (el @c{cdr}) de la
         lista.

     - De lo contrario, si el inicio de la lista (el @c{car}) falla la prueba

       - saltar ese elemento,

       - y, recursivamente llamar a la función sobre el resto (el @c{cdr}) de la
         lista.

     Aquí hay un ejemplo que usa @c{cond}:

     ..src > elisp
       (defun guardar-palabras-de-tres-letras (lista-palabras)
         "De la LISTA-PALABRAS, guarda las palabras de 3 letras."
         (cond
          ;; Primera prueba-hazlo-de-nuevo: condicion-de-parada
          ((not lista-palabras) nil)

          ;; Segunda prueba-hazlo-de-nuevo: cuando actuar
          ((eq 3 (length (symbol-name (car lista-palabras))))
           ;; combina el elemento actual con la llamada recursiva en
           ;; una lista mas corta
           (cons (car lista-palabras) (guardar-palabras-de-tres-letras (cdr lista-palabras))))

          ;; Tercera prueba-hazlo-de-nuevo: cuando saltar el elemento;
          ;; llamada recursiva con una lista mas corta con la
          ;; expresion-del-siguiente-paso
          (t (guardar-palabras-de-tres-letras (cdr lista-palabras)))))
     < src..


     ..srci > elisp
       > (guardar-palabras-de-tres-letras '(uno dos tres cuatro cinco seis))
       (uno dos)
     < srci..


     No hace falta decir que no es necesario utilizar @c{nil} como prueba
     para saber cuando parar; y, por su puesto, se pueden combinar estos patrones.

*** Recursividad sin aplazamiento

    Consideremos de nuevo lo que sucede con la función @c{triangulo-recursivo}.
    Encontraremos que los cálculos intermedios se postergan hasta que se pueda
    hacer todo.

    Aquí está la definición de función:

    ..src > elisp
      (defun triangulo-recursivo (numero)
        "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO.
      Usa recursion."
        (if (= numero 1)                    ; prueba-hazlo-de-nuevo
            1                               ; parte-then
          (+ numero                         ; parte-else
             (triangulo-recursivo           ; llamada recursiva
              (1- numero)))))               ; expresion-del-siguiente-paso
    < src..

    ¿Qué ocurre cuando llamamos a esta función con un argumento de 7?

    La primera instancia de la función @c{triangulo-recursivo} suma el
    número 7 al valor devuelto por una segunda instancia de
    @c{triangulo-recursivo}, una instancia a la que se ha pasado un argumento
    de 6. Es decir, el primer cálculo es:

    ..src > elisp
      (+ 7 (triangulo-recursivo 6))
    < src..

    La primera instancia de @c{triangulo-recursivo}––tal vez quieres pensar en
    ella como un pequeño robot––no puede completar su trabajo. Debe pasar el
    cálculo a @c{(triangulo-recursivo 6)} una segunda instancia del programa, a
    un segundo robot. Este segundo individuo es completamente diferente del
    primero; en la jerga, una ‘instancia diferente’. O, dicho de otro modo, es
    un robot diferente. Es del mismo modelo que el primero; calcula números de
    triángulo recursivamente; pero tiene un número de serie diferente.

    ¿Y qué devuelve @c{(triangulo-recursivo 6)}? Devuelve el número 6 sumado al
    valor devuelto de evaluar @c{triangulo-recursivo} con un argumento
    de 5. Usando la metáfora del robot, le pide a otro robot que lo ayude.

    Ahora el total es:

    ..src > elisp
      (+ 7 6 (triangulo-recursivo 5))
    < src..

    ¿Y qué sucede después?

    ..src > elisp
      (+ 7 6 5 (triangulo-recursivo 4))
    < src..

    Cada vez que se llama a @c{triangulo-recursivo}, excepto la última
    vez, se crea otra instancia del programa––otro robot––y le pide que
    haga un cálculo.

    Eventualmente, se establece y realiza la suma completa:

    ..src > elisp
      (+ 7 6 5 4 3 2 1)
    < src..

    Este diseño de la función aplaza el cálculo del primer paso hasta que se
    pueda hacer el segundo, y aplaza este hasta que se puede hacer el tercero,
    y así sucesivamente. Cada aplazamiento significa que el ordenador debe recordar
    lo que se está esperado. Esto no es un problema cuando solo hay unos pocos
    pasos, como en este ejemplo. Pero puede ser un problema cuando hay más
    pasos.

*** Solucion sin aplazamiento

    La solución al problema de deferir operaciones es escribir de una
    manera que no se pospongan las operaciones@n{12}. Esto requiere escribir en un
    patrón diferente, con frecuencia uno que implica escribir dos
    definiciones de función, una función de ‘inicialización’ y una función
    ‘auxiliar’.

    La función de ‘inicializacion’ configura el trabajo; la función ‘auxiliar’
    hace el trabajo.

    Aquí estan las dos definiciones de funcion para sumar números. Son tan
    simples, que me cuesta entenderlas.

    ..src > elisp
      (defun triangulo-inicializacion (numero)
        "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO.
      Este es el componente de ‘inicialización’ de una función doble
      que utiliza recursión"
        (triangulo-recursivo-auxiliar 0 0 numero))
    < src..

    ..src > elisp
      (defun triangulo-recursivo-auxiliar (suma contador numero)
        "Devuelve la SUMA, usando CONTADOR, hasta e incluyendo NUMERO.
      Este es el componente ‘auxiliar’ de una funcion doble que
      utiliza recursión."
        (if (> contador numero)
            suma
          (triangulo-recursivo-auxiliar (+ suma contador)  ; suma
                                        (1+ contador)      ; contador
                                        numero)))          ; número
    < src..

    Instala ambas definiciones de función evaluandolas, luego llama a
    @c{triangulo-inicializacion} con 2 filas:

    ..srci > elisp
      > (triangulo-inicializacion 2)
      3
    < srci..

    La función de ‘inicialización’ llama a la primera instancia de la función
    ‘auxiliar’ con tres argumentos: cero, cero, y un número que es el número
    de filas en el triángulo.

    Los dos primeros argumentos que se pasan a la función ‘auxiliar’ son valores
    de inicialización. Estos valores cambian cuando
    @c{triangulo-recursivo-auxiliar} invoca nuevas instancias.@n{13}

    Veamos que pasa cuando tenemos un triángulo que tiene una fila. (¡Este
    triángulo tendrá un guijarro en el!)

    @c{triangulo-inicializacion} llamará a su auxiliar con los argumentos @c{0 0
    1}. Esta función ejecutará la prueba condicional @c{(> contador numero)}:

    ..src > elisp
      (> 0 1)
    < src..

    y encontrara que el resultado es falso, por lo que invocara la parte-else de
    la clausula @c{if}:

    ..src > elisp
          (triangulo-recursivo-auxiliar
           (+ suma contador)  ; suma más contador   ⇒ suma
           (1+ contador)      ; incrementa contador ⇒ contador
           numero)            ; numero se mentiene igual
    < src..

    que al inicio calcula:

    ..src > elisp
      (triangulo-recursivo-auxiliar (+ 0 0)  ; suma
                                    (1+ 0)   ; contador
                                    1)       ; numero
    < src..

    que es:

    ..src > elisp
      (triangulo-recursivo-auxiliar 0 1 1)
    < src..

    Una vez mas, @c{(> contador numero)} será falso, por lo que de nuevo, el intérprete
    Lisp evaluará @c{triangulo-recursivo-auxiliar}, creando una nueva instancia
    con nuevos argumentos.

    Esta nueva instancia será;

    ..src > elisp
      (triangulo-recursivo-auxiliar
       (+ suma contador)  ; suma más contador ⇒ suma
       (1+ contador)      ; incrementa contador ⇒ contador
      numero)             ; numero se mentiene igual
    < src..

    que es:

    ..src > elisp
      (triangulo-recursivo-auxiliar 1 2 1)
    < src..

    En este caso, la prueba @c{(> contador numero)} ¡será verdadera!  Así que la
    instancia devolverá el valor de la suma, que es 1, como se esperaba.

    Ahora, vamos a pasar a @c{triangulo-inicializacion} un argumento de 2, para
    encontrar cuántos guijarros hay en un triángulo con dos filas.

    Esta función haria la llamada @c{(triangulo-recursivo-auxiliar 0 0 2)}.

    En etapas, las instancias llamadas serán:

    ..example >
                                  suma contador número
      (triangulo-recursivo-auxiliar 0    1       2)

      (triangulo-recursivo-auxiliar 1    2       2)

      (triangulo-recursivo-auxiliar 3    3       2)
    < example..

    Cuando se llama a la última instancia, la prueba @c{(> contador numero)}
    será verdadera, por lo que la instancia devolverá el valor de @c{suma}, que
    será 3.

    Este tipo de patrón ayuda cuando estás escribiendo funciones que pueden
    usar muchos recursos en un ordenador.

** Ejercicio de bucles

   - Escribe una función similar a @c{triangulo} en la que cada fila tenga un
     valor que sea el cuadrado del número de la fila. Usa un bucle @c{while}.

   - Escribe una función similar a @c{triangulo} que multiplique en lugar de
     sumar los valores.

   - Reescribe estas dos funciones recursivamente. Reescribe estas funciones
     usando @c{cond}.

   - Escribe una función para el modo Texinfo que cree una entrada índice al
     principio de un párrafo para cada @'{@@dfn} dentro del parrafo. (En un
     fichero Texinfo, @'{@@dfn} marca una definición.)

     Muchas de las funciones que necesitaras se describen en los dos capitulos anteriores,
     Secciones @l{#Cortar y Almacenar Texto} y @l{#Traer de regreso el texto}. Si usas
     @c{forward-paragraph} para poner la entrada de índice al principio del
     párrafo, tendrás que usar @k{C-h f} @%c{describe-function} para
     averiguar como hacer que el comando vaya hacia atrás.

   Para obtener más información, consulta la Seccion
   @l{https://www.gnu.org/software/texinfo/manual/texinfo/texinfo.html#Indicating<>Indicando Definiciones, Comandos, etc.}  en el
   @e{Manual de Texinfo} dentro de Emacs. O, tambien puedes consultarlo en
   internet en @l{http://www.gnu.org/software/texinfo/manual/texinfo/}

* Búsqueda de expresiones regulares

  Las búsquedas de expresiones regulares se utilizan extensivamente en GNU
  Emacs. Las dos funciones @c{forward-sentence} y @c{forward-paragraph},
  ilustran bien estas búsquedas. Usan expresiones regulares para encontrar
  donde mover el punto. La frase ‘expresión regular’ se escribe a menudo
  como ‘regexp’.

  Las búsquedas de expresiones regulares se describen en la Seccion
  @l{emacs.html#Regexp Search<>Búsqueda de Expresiónes Regulares} en @e{El
  Manual de GNU Emacs}, asi como en la Seccion @l{elisp.html#Regular
  Expressions<>Expresiones Regulares} en @e{El Manual de Referencia de GNU Emacs
  Lisp}. Al escribir este capítulo, estoy suponiendo que tienes al menos un leve
  conocimiento de esto. El punto principal a recordar es que las expresiones
  regulares te permiten buscar patrones, asi como cadenas literales de
  caracteres. Por ejemplo, el código en @c{forward-sentence} busca el patrón de
  posibles caracteres que podrían marcar el final de una oracion, y mueve el
  punto a ese lugar.

  Antes de mirar el código de la función @c{forward-sentence}, vale la pena
  considerar cual debe ser el patrón que marca el final de una oracion. El
  patrón se discute en la siguiente sección; a continuacion se describe
  la funcion de busqueda de expresiónes regulares, @c{re-search-forward}. La función
  @c{forward-sentence} se describe en la sección siguiente. Finalmente, la
  función @c{forward-paragraph} se describe en la última sección de este
  capítulo. @c{forward-paragraph} es una función compleja que introduce
  varias caracteristicas nuevas.

** La expresión regular de @c{sentence-end}

   El símbolo @c{sentence-end} esta ligado al patrón que marca el fin de una
   oracion. ¿Cuál deberia ser esta expresión regular?

   Claramente, una oracion puede terminarse por un punto, un signo de
   interrogación, o un signo de exclamación. De hecho, en inglés, solo las
   oraciones que terminan con uno de estos tres caracteres deberían considerse
   como el final de una oracion. Esto significa que el patrón debe incluir el
   conjunto de caracteres:

   ..example >
     [.?!]
   < example..

   Sin embargo, no queremos que @c{forward-sentence} salte simplemente a un
   punto, a un signo de interrogacion o a un signo de exclamación, porque tal
   carácter podría utilizarse en medio de una oracion. Un punto, por ejemplo,
   se usa después de las abreviaturas. Por lo tanto, se necesita mas información.

   Segun la convención, escribes dos espacios despues de cada oracion, pero solo
   un espacio después de un punto, un signo de interrogacion o un signo de
   exclamación en el cuerpo de una oracion. Asi que un punto, un signo de
   interrogacion o de exclamacion seguido por dos espacios es un buen indicador
   de un final de oracion. Sin embargo, en un archivo, los dos espacios pueden
   ser un tabulador o el fin de una línea. Esto significa que la expresión
   regular incluiría estos tres elementos como alternativas.

   Este grupo de alternativas se vera asi:

   ..example >
     \\($\\| \\|  \\)
            ^   ^^
           TAB  SPC
   < example..

   Aquí, @'c{$} indica el fin de la línea, ademas he señalado en la expresión
   donde se inserta el tabulador y los dos espacios. Ambos se insertan poniendo
   los caracteres reales en la expresión.

   Antes de los parentesis y las barras verticales, se requiere dos
   barras invertidas @'c{\\}: la primera barra invertida cita la
   siguiente barra invertida en Emacs; y la segunda indica que el siguiente
   caracter, el paréntesis o la barra vertical, es especial.

   También, una oracion puede ir seguida por uno o más retornos de carro, como
   aqui:

   ..example >
     [
     ]*
   < example..

   Al igual que los tabuladores y espacios, un retorno de carro se inserta en
   una expresión regular insertándolo literalmente. El asterisco indica
   que el @k{RET} se repite cero o más veces.

   Pero una oracion no consiste solo en un punto, o un signo de interrogacion o
   de exclamación seguido de un espacio apropiado: una comilla de cierre o una
   llave de cierre de algún tipo puede preceder al espacio. De hecho, más de una
   marca o paréntesis pueden preceder al espacio. Estas requieren una expresión
   parecida a esta:

   ..example >
     []\"')}]*
   < example..

   En esta expresión, el primer @'c{]} es el primer caracter en la expresión;
   el segundo caracter es @'c{"}, que está precedido por un @'c{\} para decirle
   a Emacs que el @'c{"} @e{no} es especial. Los últimos tres caracteres son @'c{'},
   @'c{)}, y @'c(}).

   Todo esto sugiere cual deberia ser el patrón de la expresión regular para que
   coincida con el final de una oracion; y, de hecho, si evaluamos
   @c{sentence-end} encontraremos que devuelve el siguiente valor:

   ..srci > elisp
     > sentence-end
     "[.?!][]\"')}]*\\($\\|     \\|  \\)[
     ]*"
   < srci..

   (Bueno, no en GNU Emacs 22; eso se debe a un esfuerzo por hacer el proceso
   simple y manejar más símbolos y lenguajes. Cuando el valor de
   @c{sentence-end} es @c{nil}, entonces utiliza el valor definido por la
   función @c{sentence-end}. (Aquí se utiliza la diferencia entre un valor y una
   función en Emacs Lisp.) La función devuelve un valor construido a partir de
   las variables @c{sentence-end-base}, @c{sentence-end-double-space},
   @c{sentence-end-without-period}, y @c{sentence-end-without-space}. La
   variable crítica es @c{sentence-end-base}; su valor global es similar al
   descrito anteriormente, pero también contiene dos marcas de cita
   adicionales. Estas tienen diferentes grados de curvatura. La variable
   @c{sentence-end-without-period}, cuando es verdadera, le dice a Emacs que una
   oracion puede finalizar sin un punto, como en texto en Tailandés.)

** La Función @c{re-search-forward}

   La función @c{re-search-forward} es similar a la función
   @c{search-forward}. (Consulta la Seccion @l{#La Función @c{search-forward}}.)

   @c{re-search-forward} busca una expresión regular. Si la búsqueda es exitosa,
   deja el punto inmediatamente después del último caracter en el objetivo. Si
   la búsqueda es hacia atrás, deja el punto antes del primer caracter en el
   objetivo. Puedes decirle a @c{re-search-forward} que regrese @c{t} por
   verdadero. (El movimiento del punto es por la tanto un ‘efecto secundario’.)

   Al igual que @c{search-forward}, la función @c{re-search-forward} toma cuatro
   argumentos:

   1. El primer argumento es la expresión regular que busca la función. La
      expresión regular será una cadena entre comillas.

   2. El segundo argumento opcional limita el grado de busqueda de la función;
      es un valor ligado con una posición especifica en el búfer.

   3. El tercer argumento opcional especifica cómo la función responde al
      fallo: @c{nil} como tercer argumento hace que la función señale
      un error (e imprima un mensaje) cuando la búsqueda falla; cualquier
      otro valor hace que devuelva @c{nil} si la búsqueda falla y @c{t} si la
      búsqueda tiene éxito.

   4. El cuarto argumento opcional es el contador de repeticiones. Un contador
      de repeticion negativo hace que @c{re-search-forward} busque hacia atrás.


   La plantilla para @c{re-search-forward} se ve asi:

   ..src > elisp
     (re-search-forward "expresion-regular"
                        limite-de-busqueda
                        que-hacer-si-falla-la-busqueda
                        contador-de-repeticiones)
   < src..

   El segundo, tercer, y cuarto argumentos son opcionales. Sin embargo, si se
   quiere pasar un valor a uno o ambos de los últimos dos argumentos, se debe
   también pasar un valor a todos los argumentos anteriores. De otro modo,
   el intérprete Lisp confundira el argumento al que estás pasando el valor.

   En la función @c{forward-sentence}, la expresión regular será el valor de
   la variable @c{sentence-end}. En forma simple, esto es:

   ..example >
     "[.?!][]\"')}]*\\($\\|  \\|  \\)[
     ]*"
   < example..

   El límite de la búsqueda será el fin del párrafo (ya que una oracion no puede
   ir mas alla de un párrafo). Si la búsqueda falla, la función devuelve @c{nil}, y
   el argumento del contador de repeticion será pasado a la función
   @c{forward-sentence}.

** La Función @c{forward-sentence}

   El comando para mover el cursor hacia adelante una oracion es una
   ilustración directa de cómo usar búsqueda de expresiones regulares en Emacs
   Lisp. De hecho, la función parece más larga y más complicada de lo que es;
   esto se debe a que la función está diseñada para ir hacia atrás y hacia
   adelante; y, opcionalmente, mas de una oracion. La función normalmente
   está vinculada al comando @k{M-e}.

   Aquí está la código de @c{forward-sentence}:

   ..src > elisp
     (defun forward-sentence (&optional arg)
       "Avansa al siguiente ‘sentence-end’. Con un argumento, se repite.
     Con un argumento negativo, avanza hacia atras repetidamente al ‘sentence-beginning’.

     La variable ‘sentence-end’ es una expresión regular que corresponde al
     fin de la oracion. Ademas, cada limite de párrafo tambien termina una oracion."
       (interactive "p")
       (or arg (setq arg 1))
       (let ((opoint (point))
             (sentence-end (sentence-end)))
         (while (< arg 0)
           (let ((pos (point))
                 (par-beg (save-excursion (start-of-paragraph-text) (point))))
            (if (and (re-search-backward sentence-end par-beg t)
                     (or (< (match-end 0) pos)
                         (re-search-backward sentence-end par-beg t)))
                (goto-char (match-end 0))
              (goto-char par-beg)))
           (setq arg (1+ arg)))
         (while (> arg 0)
           (let ((par-end (save-excursion (end-of-paragraph-text) (point))))
            (if (re-search-forward sentence-end par-end t)
                (skip-chars-backward " \t\n")
              (goto-char par-end)))
           (setq arg (1- arg)))
         (constrain-to-field nil opoint t)))
   < src..

   La función se ve larga a primera vista y lo mejor es mirar primero su
   esqueleto, y luego su músculo. La forma de ver el esqueleto es mirar
   las expresiones que comienzan en las columnas de la izquierda:

   ..src > elisp
     (defun forward-sentence (&optional arg)
       "documentacion…"
       (interactive "p")
       (or arg (setq arg 1))
       (let ((opoint (point)) (sentence-end (sentence-end)))
         (while (< arg 0)
           (let ((pos (point))
                 (par-beg (save-excursion (start-of-paragraph-text) (point))))
            resto-del-cuerpo-del-bucle-while-cuando-va-hacia-atras
         (while (> arg 0)
           (let ((par-end (save-excursion (end-of-paragraph-text) (point))))
            resto-del-cuerpo-del-bucle-while-cuando-va-hacia-adelante
         manejar-formularios-y-equivalentes
   < src..

   ¡Esto parece mucho mas simple! La definición de la función consiste en la
   documentación, una expresión @c{interactive}, una expresión @c{or}, una
   expresión @c{let}, y bucles @c{while}.

   Veamos cada una de estas partes por separado.

   Observamos que la documentación es completa y comprensible.

   La función tiene una declaración @c{interactive "p"}. Esto signifca que el
   argumento prefijo procesado, si lo hay, pasa a la función como su
   argumento. (Este será un número.) Si no se pasa un argumento a la función (es
   opcional) entonces el argumento @c{arg} será vinculara a 1.

   Cuando @c{forward-sentence} se llama no interactivamente sin un argumento,
   @c{arg} está vinculado a @c{nil}. La expresión @c{or} maneja esto. Lo que
   hace es dejar el valor de @c{arg} como esta, pero solo si @c{arg} está ligado
   a un valor; de otro modo asigna el valor de @c{arg} a 1, en el caso de que
   @c{arg} este ligado a @c{nil}.

   Lo siguiente es un @c{let}. Especifica los valores de dos variables
   locales @c{point} y @c{sentence-end}. El valor local del punto, desde antes
   de la búsqueda, se utiliza en la función @c{constrain-to-field} que maneja
   formularios y equivalentes. La variable @c{sentence-end} se establece por
   la función @c{sentence-end}.

*** Los bucles @c{while}

    Siguen dos bucles @c{while}. El primer @c{while} tiene una
    prueba-verdadero-o-falso que es verdadero si el argumento prefijo de
    @c{forward-sentence} es un número negativo. Esto es para ir hacia atras. El
    cuerpo de este bucle es similar al cuerpo del segundo @c{while},
    pero no es exactamente el mismo. Pasaremos de este bucle @c{while} y
    nos centraremos en el segundo @c{while}.

    El segundo bucle @c{while} es para mover el punto hacia adelante. Su
    esqueleto luce asi:

    ..src > elisp
      (while (> arg 0)            ; prueba-verdadero-o-falso
        (let varlist
          (if (prueba-verdadero-o-falso)
              parte-then
            parte-else
        (setq arg (1- arg))))     ; decremento del bucle while
    < src..

    El bucle @c{while} es de tipo decreciente. (Consulta la Seccion @l{#Bucle con
    un contador decreciente}.) Tiene una prueba-verdadero-o-falso que regresa
    verdadero siempre y cuando el contador (en este caso, la variable @c{arg})
    sea mayor que cero; y tiene un decremento que resta 1 del valor del contador
    cada vez que el bucle se repite.

    Si no se da un argumento prefijo a @c{forward-sentece}, que es lo mas
    habitual, este bucle @c{while} se ejecutará una vez, ya que el valor de
    @c{arg} será 1.

    El cuerpo del bucle @c{while} consite en una expresión @c{let}, que crea
    y vincula una variable local, y tiene, como su cuerpo, una expresión @c{if}.

    El cuerpo del bucle @c{while} se ve asi:

    ..src > elisp
      (let ((par-end
             (save-excursion (end-of-paragraph-text) (point))))
        (if (re-search-forward sentence-end par-end t)
            (skip-chars-backward " \t\n")
          (goto-char par-end)))
    < src..

    La expresión @c{let} crea y enlaza la variable local @c{par-end}. Como
    veremos, esta variable local está diseñada para proporcionar un limite a la
    búsqueda de expresiónes regulares. Si la búsqueda no encuentra una
    oracion apropiada que termine en el párrafo, se detendra al llegar al final
    del párrafo.

    Pero primero, examinaremos cómo @c{par-end} se liga al valor del
    fin del párrafo. Lo que ocurre es que el @c{let} asigna el
    valor de @c{par-end} al valor devuelto cuando el intérprete evalúa la
    expresión.

    ..src > elisp
      (save-excursion (end-of-paragraph-text) (point))
    < src..

    En esta expresión, @c{(end-of-paragraph-text)} mueve el punto al fin del
    párrafo, @c{(point)} devuelve el valor del punto, y luego
    @c{save-excursion} restaura el punto a su posición original. De este
    modo, el @c{let} liga @c{par-end} al valor devuelto por la expresión
    @c{save-excursion}, que es la posición del fin del párrafo.  (La función
    @c{end-of-paragraph-text} utiliza @c{forward-paragraph}, que discutiremos en
    breve.)

    A continuacion Emacs evalúa el cuerpo del @c{let}, que es una expresión
    @c{if}:

    ..src > elisp
      (if (re-search-forward sentence-end par-end t) ; parte-if
          (skip-chars-backward " \t\n")              ; parte-then
        (goto-char par-end)))                        ; parte-else
    < src..

    El @c{if} comprueba si su primer argumento es verdadero y es así, evalúa su
    parte-then; de lo contrario, el intérprete Emacs Lisp evalúa la parte-else.
    La prueba-verdadero-o-falso de la expresión @c{if} es la búsqueda de la
    expresión regular.

    Puede parecer extraño tener lo que parece ser el ‘trabajo real’ de la función
    @c{forward-sentence} enterrado aqui, pero esta es una forma común de
    realizar este tipo de operación en Lisp.

*** La búsqueda de expresiones regulares

    La función @c{re-search-forward} busca el fin de la oracion, es decir, el
    patrón definido por la expresión regular @c{sentence-end}. Si se encuentra
    el patrón––si se encuentra el fin de la oracion––entonces la función
    @c{re-search-forward} hace dos cosas:

    1. La función @c{re-search-forward} realiza un efecto secundario, que es mover
       el punto al final de la ocurrencia encontrada.

    2. La función @c{re-search-forward} devuelve un valor verdadero. Este es
       el valor recibido por el @c{if}, y significa que la búsqueda fué
       exitosa.


    El efecto secundario, el movimiento del punto se completa antes de que la
    función @c{if} reciva el valor devuelto por la conclusión exitosa de la
    búsqueda.

    Cuando la función @c{if} recibe el valor verdadero desde una llamada exitosa
    a @c{re-search-forward}, el @c{if} evalúa la parte-then que es la expresión
    @c{(skip-chars-backward "\t\n")}. Esta expresión se mueve hacia atrás a
    través de cualquier espacio en blanco, tabulador o retorno de carro hasta
    encontrar un caracter imprimible y deja el punto después del caracter.
    Como el punto ya se ha movido al final del patron que marca el final de la
    oracion, esta accion deja el punto justo despues del caracter imprimible de
    cierre de la oracion, que suele ser un punto.

    Por otro lado, si la función @c{re-search-forward} no encuentra
    un patrón que marque el fin de la oracion, la función devuelve falso. El
    falso hace que @c{if} evalue su tercer argumento, que es
    @c{(goto-char par-end)}: esto mueve el punto al final del párrafo.

    (Y si el texto está en una forma o equivalente, y el punto no se
    mueve completamente, entonces entra en juego la función
    @c{constrain-to-field}.)

    La búsqueda de expresiones regulares son excepcionalmente útiles y el
    patrón ilustrado por @c{re-search-forward}, en el que la búsqueda es la
    prueba de una expresión @c{if}, es facil de manejar. Veras o escribirás código
    incorporando este patrón con frecuencia.

** @c{forward-paragraph}: una mina de oro de funciones

   La función @c{forward-paragraph} mueve el punto al fin del párrafo. Por
   lo general esta asociado a @k(M-}) y hace uso de un número de funciones
   que son importantes en sí mismas, incluyendo @c{let*}, @c{match-beginning}, y
   @c{looking-at}.

  La definición de función de @c{forward-paragraph} es considerablemente
   mas extensa que la definición de función de @c{forward-sentence} porque
   trabaja con un párrafo, cada línea de la cual puede empezar con un prefijo de
   relleno.

   Un prefijo de relleno consiste en una cadena de caracteres que se repite al
   principio de cada línea. Por ejemplo, en el código Lisp, es una convención
   empezar cada línea de un comentario de un párrafo extenso con @'{;;; }. En el
   modo Texto, cuatro espacios en blanco forman otro prefijo común de relleno,
   creando un párrafo indentado. (Consulta la Sección @l{emacs.html#Fill
   Prefix<>Prefijo de relleno} en @e(El Manual de GNU Emacs) para más
   información acerca de los prefijos de relleno.)

   La existencia de un prefijo de relleno significa que, además de poder
   encontrar el fin de un párrafo cuyas líneas empiezan en la columna más a la
   izquierda, la función @c{forward-paragraph} debe ser capaz de encontrar el
   final de un párrafo cuando todas o muchas de las líneas en el búfer
   empiezan con el prefijo de relleno.

   Ademas, a veces es práctico ignorar un prefijo de relleno que existe,
   especialmente cuando las líneas en blanco separan los párrafos. Esto es una
   complicación añadida.

   En vez de imprimir toda la función @c{forward-paragraph}, solo
   imprimiremos partes de la misma. ¡Leer la función sin preparación, puede
   ser desalentador!

   En general, la función tiene este aspecto:

   ..src > elisp
     (defun forward-paragraph (&optional arg)
       "documentacion…"
       (interactive "p")
       (or arg (setq arg 1))
       (let*
           varlist
         (while (and (< arg 0) (not (bobp)))     ; codigo-de-movimiento-hacia-atras
           …
         (while (and (> arg 0) (not (eobp)))     ; codigo-de-movimiento-hacia-adelante
           …
   < src..

   Las primeras partes de la función son rutinarias: la  lista de argumentos
   de la función consiste en un argumento opcional. Luego se presenta
   la documentación.

   La letra minúscula @'c{p} en la declaración @c{interactive} significa que el
   argumento prefijo se procesa, si lo hay, pasa a la función. Este será un
   número, y es el contador de repeticion de cuántos párrafos se moverá el
   punto. La expresión @c{or} en la siguiente línea maneja el caso común cuando
   no se pasa ningun argumento a la función, esto ocurre si la función se
   llama desde otro código en lugar de interactivamente. Este caso se describio
   anteriormente. (Consulta la Seccion @l{#La Función @c{forward-sentence}}.) Ahora
   llegamos al final de la parte familiar de esta función.

*** La expresión @c{let*}

    La siguiente línea en la función @c{forward-paragraph} empieza con una
    expresión @c{let*}. Esto es diferente a @c{let}. El símbolo es
    @c{let*} no @c{let}.

    La forma especial @c{let*} es como @c{let} excepto que Emacs establece cada
    variable en secuencia, una después de otra, y las variables en la última
    parte de la varlist pueden hacen uso de los valores a los que Emacs asignó
    las variables al principio la varlist.

    (Seccion @l{#@c{save-excursion} en @c{append-to-buffer}}.)

    En la expresión @c{let*} en esta función, Emacs asigna un total de siete
    variables: @c{opoint}, @c{fill-prefix-regexp}, @c{parstart}, @c{parsep},
    @c{sp-parstart}, @c{start}, y @c{found-start}.

    La variable @c{parsep} aparece dos veces, primero, para eliminar instancias
    de @'c{^}, y segundo, para manejar prefijos de relleno.

    La variable @c{opoint} es solo el valor de @c{point}. Como se puede
    adivinar, se usa en una expresión @c{constrain-to-field}, igual que
    en @c{forward-sentence}.

    La variable @c{fill-prefix-regexp} se establece con el valor devuelto de
    evaluar la siguiente lista:

    ..src > elisp
      (and fill-prefix
           (not (equal fill-prefix ""))
           (not paragraph-ignore-fill-prefix)
           (regexp-quote fill-prefix))
    < src..

    Esta es una expresión cuyo primer elemento es la forma especial @c{and}.

    Como aprendimos anteriormente (Sección @l(#La función @c{kill-new})), la
    forma especial @c{and} evalúa cada uno de sus argumentos hasta uno de los
    argumentos devuelve un valor @c{nil}, en cuyo caso la expresión @c{and}
    devuelve @c{nil}; sin embargo, si ninguno de los argumentos devuelve un
    valor @c{nil}, se devuelve el valor resultante de evaluar el último
    argumento. (Puesto que tal valor no es @c{nil}, se considera verdadero en
    Lisp.) En otras palabras, una expresión @c{and} devuelve un valor verdadero
    solo si todos sus argumentos son verdaderos.

    En este caso, la variable @c{fill-prefix-regexp} se vincula a un valor no
    @c{nil} solo si las cuatro expresiones siguientes producen un valor
    verdadero (es decir, un valor no @c{nil}) cuando se evalúan; de lo
    contrario, la variable @c{fill-prefix-regexp} se vincula a @c{nil}.

    - @c(fill-prefix) ::

      Cuando se evalua esta variable, se devuelve el valor del prefijo de
      relleno, si lo hay. Si no hay ningun prefijo relleno, esta variable devuelve
      @c{nil}.

    - @c[(not (equal fill-prefix "")] ::

      Esta expresión comprueba si un prefijo de relleno existente es una cadena
      vacía, es decir, una cadena sin caracteres. Una cadena vacía no es
      un prefijo de relleno útil.

    - @c[(not paragraph-ignore-fill-prefix)] ::

      Esta expresión devuelve @c{nil} si la variable
      @c{paragraph-ignore-fill-prefix} ha sido activada al asignarle un valor
      verdadero como @c{t}.

    - @c[(regexp-quote fill-prefix)] ::

      Este es el último argumento pasado a la forma especial @c{and}. Si todos
      los argumentos de @c{and} son verdaderos, el valor resultante de
      evaluar esta expresión será devuelto por la expresión @c{and} y
      asociado a la variable @c{fill-prefix-regexp},


    El resultado de evaluar esta expresión @c{and} con éxito es que
    @c{fill-prefix-regexp} sera ligada al valor de @c{fill-prefix} como fué
    modificado por la función @c{regexp-quote}. Lo que @c{regexp-quote} hace es
    leer una cadena y devolver la expresión regular que coincida exactamente con
    la cadena y nada más. Esto significa que el valor de @c{fill-prefix-regexp} será
    asignado a un valor que coincida exactamente con el prefijo si existe. De lo
    contrario, la variable sera ligada a @c{nil}.

    Las siguientes dos variables locales en la expresión @c{let*} están
    diseñadas para eliminar instancias de @'c{^} de @c{parstart} y @c{parsep},
    las variables locales que indican el inicio del párrafo y el separador de
    párrafos. La siguiente expresión define @c{parsep} de nuevo. Esto es para
    manejar prefijos de relleno.

    Esta es la configuracion que requiere la llamada de la definición
    @c{let*} en lugar de @c{let}. La prueba-verdadero-o-falso del @c{if} depende
    de si la variable @c{fill-prefix-regexp} se evalúa a @c{nil} o algún otro
    valor.

    Si @c{fill-prefix-regexp} no tiene un valor, Emacs evalúa la parte-else
    de la expresión @c{if} y vinculara @c{parsep} a su valor local. (@c{parsep}
    es una expresión regular que coincide con la separacion de párrafos.)

    Pero si @c{fill-prefix-regexp} tiene un valor, Emacs evalúa la parte-then
    de la expresión @c{if} y enlaza @c{parsep} a una expresión regular que
    incluye @c{fill-prefix-regexp} como parte del patrón.

    Específicamente, @c{parsep} se asigna al valor original del separador del
    párrafo, la expresión regular concatenada con una expresión alternativa que
    consiste en @c{fill-prefix-regexp} seguido por espacios en blanco opcionales
    halta el fin de la línea. (El espacio en blanco se define con @"c{[ \t]*$}.)
    El @'{\\|} define esta porción de la regexp como una alternativa a @c{parsep}.

    De acuerdo a un comentario en el código, la siguiente variable local,
    @c{sp-parstart}, se utiliza para la busqueda, y luego los dos finales,
    @c{start} y @c{found-start}, se asignan a @c{nil}.

    Ahora entramos en el cuerpo del @c{let*}. La primera parte del cuerpo del
    @c{let*} trata el caso cuando la función recibe un argumento negativo y por
    lo tanto se mueve hacia atrás. Omitiremos esta sección.

*** El bucle @c{while} hacia adelante

    La segunda parte del cuerpo del @c{let*} se ocupa del movimiento hacia
    adelante. Es un bucle @c{while} que se repite mientras el valor de @c{arg}
    sea mayor a cero. En el uso más común de la función el valor del argumento es
    1, por lo que el cuerpo del bucle @c{while} se evalúa exactamente una vez, y
    el cursor avanza hacia adelante un párrafo.

    Esta parte maneja tres situaciones: cuando el punto está entre párrafos,
    cuando hay un prefijo de relleno y cuando no hay un prefijo de relleno.

    El bucle @c{while} se ve así:

    ..src > elisp
      ;; avanza hacia adelante y no al final del búfer
      (while (and (> arg 0) (not (eobp)))

        ;; entre párrafos
        ;; Avanzar sobre lineas de separacion...
        (while (and (not (eobp))
                    (progn (move-to-left-margin) (not (eobp)))
                    (looking-at parsep))
          (forward-line 1))
        ;;  Esto decrementa el bucle
        (unless (eobp) (setq arg (1- arg)))
        ;; ... y una línea más
        (forward-line 1)

        (if fill-prefix-regexp
            ;; Hay un prefijo de relleno; sobreescribe parstart;
            ;; avanzamos línea a línea
            (while (and (not (eobp))
                        (progn (move-to-left-margin) (not (eobp)))
                        (not (looking-at parsep))
                        (looking-at fill-prefix-regexp))
              (forward-line 1))

          ;; No hay prefijo de relleno;
          ;; avanzamos caracter por caracter
          (while (and (re-search-forward sp-parstart nil 1)
                      (progn (setq start (match-beginning 0))
                             (goto-char start)
                             (not (eobp)))
                      (progn (move-to-left-margin)
                             (not (looking-at parsep)))
                      (or (not (looking-at parstart))
                          (and use-hard-newlines
                               (not (get-text-property (1- start) 'hard)))))
            (forward-char 1))

          ;; y si no hay prefijo de relleno y si no estamos al final
          ;; ir a lo que se encontro en la búsqueda de expresiones regulares
          ;; para sp-parstart
          (if (< (point) (point-max))
              (goto-char start))))
    < src..

    Podemos ver que se trata de un contador de decremento @c{while}, usando la
    expresión @c{(setq arg (1- arg))} como decrementador. Esta expresión no está
    lejos del @c{while}, pero está oculta en otra macro Lisp, una macro
    @c{unless}. A menos que estemos al final del búfer––eso es lo que determina
    la función @c{eobp}; es una abreviación de @'{End of Buffer P}––disminuimos
    el valor de @c{arg} por uno.

    (Si estamos al fin del búfer, ya no podemos avanzar mas y el siguiente bucle
    de la expresión @c{while} sera falso ya que la prueba es un @c{and} con
    @c{(not (eobp))}. La función @c{not} significa exactamente lo que se espera;
    es otro nombre para @c{null}, una función que devuelve verdadero cuando su
    argumento es falso.)

    Curiosamento, el contador del bucle no disminuye hasta que dejamos el
    espacio entre párrafos, a menos que lleguemos al fin del búfer o dejemos de
    ver el valor local del separador del párrafo.

    El segundo @c{while} también tiene una expresión @c{(move-to-left-margin)}.
    La función es autoexplicativa. Está dentro de una expresión @c{progn} y no
    es el último elemento de su cuerpo, por lo que solo se invoca por su efecto
    secundario, que es mover el punto al margen izquierdo de la línea actual.

    La función @c{looking-at} también es auto-explicativa; devuelve
    verdadero si el texto después del punto coincide con la expresión regular dada
    como su argumento.

    El resto del cuerpo del bucle parece complejo al principio, pero tiene
    sentido a medida que se llega a entender.

    Primero considera lo que sucede si hay un prefijo de relleno:

    ..src > elisp
      (if fill-prefix-regexp
          ;; Hay un prefijo de relleno; sobreescribe parstart;
          ;; avanzamos línea a línea
          (while (and (not (eobp))
                      (progn (move-to-left-margin) (not (eobp)))
                      (not (looking-at parsep))
                      (looking-at fill-prefix-regexp))
            (forward-line 1))
    < src..

    Esta expresión mueve el punto hacia adelante línea por línea siempre y
    cuando se cumplan cuatro condiciones:

    1. El punto no está al final del búfer.

    2. Podemos movernos al margen izquierdo del texto y no estamos al fin del
       búfer.

    3. El texto siguiente al punto no separa los párrafos.

    4. El patrón que sigue al punto es la expresión regular del prefijo de relleno.


    La última condición puede ser un puzzle, hasta que se recuerde qué el punto
    fue movido al principio de la línea anteriormente en la función
    @c{forward-paragraph}. Esto significa que si el texto tiene un prefijo
    de relleno, la función @c{looking-at} lo verá.

    Considera qué ocurre cuando no hay un prefijo lleno.

    ..src > elisp
      (while (and (re-search-forward sp-parstart nil 1)
                  (progn (setq start (match-beginning 0))
                         (goto-char start)
                         (not (eobp)))
                  (progn (move-to-left-margin)
                         (not (looking-at parsep)))
                  (or (not (looking-at parstart))
                      (and use-hard-newlines
                           (not (get-text-property (1- start) 'hard)))))
        (forward-char 1))
    < src..

    El bucle @c{while} nos lleva a la busqueda de @c{sp-parstart}, que es la
    combinación de posibles espacios en blanco con el valor local del inicio de
    un párrafo o de un separador de párrafos. (Los dos últimos se encuentran
    dentro de una expresión que comienza con @c{\(?:} así que no están
    referenciados por la función @c{match-beginning}.)

    Las dos expresiones,

    ..src > elisp
      (setq start (match-beginning 0))
      (goto-char start)
    < src..

    significan ir al comienzo del texto localizado con la expresión regular.

    La expresión @c{(match-beginning 0)} es nueva. Devuelve un número que
    especifica la ubicacion del inicio del texto que coincidio con la última
    búsqueda.

    La función @c{match-beginning} se utiliza aquí debido a una característica
    de la búsqueda hacia adelante: una búsqueda exitosa hacia adelante,
    independientemente de si se trata de una búsqueda simple o de una con expresiónes
    regulares, mueve el punto al fin del texto que encuentra. En este caso,
    una búsqueda exitosa mueve el punto al fin del patrón de @c{sp-parstart}.

    Sin embargo, queremos poner el punto al fin del actual párrafo, no en algún
    otro lugar. De hecho, dado que la búsqueda posiblemente incluye el separador
    de párrafos, el punto puede finalizar al principio del siguiente a menos que
    utilicemos una expresión que incluya @c{match-beginning}.

    Cuando se le da un argumento de 0, @c{match-beginning} devuelve la posición
    de inicio del texto coincidente con la búsqueda más reciente. En este caso,
    la búsqueda más reciente de @c{sp-parstart}. La expresión
    @c{(match-beginning 0)} devuelve la posición inicial de ese patrón, en
    lugar de la posición final.

    (Incidentalmente, cuando se pasa un número positivo como argumento, la
    función @c{match-beginning} devuelve la ubicacion del punto de la
    expresión con paréntesis en la última búsqueda a menos que la expresión con
    paréntesis empiece con @c{\(?:}. No sé porque @c{\(?:} aparece aquí, ya que
    el argumento es 0.)

    La última expresión cuando no hay prefijo de relleno es

    ..src > elisp
      (if (< (point) (point-max))
          (goto-char start))))
    < src..

    Esto dice que si no hay un prefijo de relleno y no estamos al final, el punto
    deberia moverse al principio de lo que sea que sea haya encontrado al buscar la
    expresión regular de @c{sp-parstart}.

    La definición completa de la función @c{forward-paragraph} no solo
    incluye código para avanzar, sino también código para retroceder.

    Si estás leyendo esto dentro de GNU Emacs y quieres ver la función
    completa, puedes escribir @k{C-h f} @%c(describe-function) y el nombre
    de la función. Esto proporciona la documentación de función y el nombre de la
    librería que contiene el codigo fuente de la función. Coloca el punto sobre
    el nombre de la librería y presionar la tecla @k(RET); serás llevado
    directamente al codigo fuente. (¡Asegúrate de instalar el codigo fuente! ¡Sin
    el, eres como una persona que intenta conducir un coche con los ojos
    cerrados!)

** Crea tu propio fichero @f{TAGS}

   Ademas de @k{C-h f} @%c(describe-function), otra forma de ver el codigo de
   una función es escribir @k{M-.} @%c(find-tag) y el nombre de la función
   cuando se solicite. Es un buen hábito para obtenerlo. El comando @k{M-.}
   @%c(find-tag) te lleva directamente al codigo de una función, variable, o
   nodo. La función depende de tablas de etiquetas para saber donde ir.

   Si la función @c{find-tag} pregunta primero por el nombre de una tabla
   @f{TAGS}, dale el nombre de un fichero @f{TAGS} como
   @f{/usr/local/src/emacs/src/TAGS}. (La ruta exacta a tu fichero @f{TAGS}
   depende de cómo instalaste tu copia de Emacs. Yo proporcione la localización
   tanto de mi codigo fuente de C, como de Emacs Lisp.)

   Tambien puedes crear tu propio fichero @f{TAGS} para directorios que
   carecen de uno.

   Con frecuencia se necesita construir e instalar tablas de etiquetas por
   cuenta propia. No se construiyen automáticamente. Una tabla de etiquetas
   es un fichero que lleva por nombre @f{TAGS}; el nombre esta en letras mayúsculas.

   Puedes crear un fichero @f{TAGS} llamando al programa @c{etags} que
   viene como parte de la distribución de Emacs. Por lo general, @c{etags} se
   compila e instala cuando se construye Emacs. (@c{etags} no es una
   función Lisp ni parte de Emacs; es un programa C.)

   Para crear el fichero @f{TAGS}, primero cambia al directorio en el que
   deseas crear el fichero. En Emacs se puede hacer esto con el comando
   @k{M-x cd}, o visitando un fichero en el directorio, o listando el
   directorio con @k{C-x d} @%c(dired). A continuacion, ejecuta el comando
   @c(compile), con @${etags *.el} como el comando a ejecutar

   ..example >
     M-x compile RET etags *.el RET
   < example..

   para crear un fichero @f{TAGS} para Emacs Lisp.

   Por ejemplo, si se tiene un gran número de ficheros en el directorio
   @f{~/emacs}, como en mi caso––yo tengo 137 ficheros @f{.el}, de los cuales cargo
   12––se puede crear un fichero @f{TAGS} para los ficheros Emacs Lisp en
   ese directorio.

   El programa @${etags} recive todos los ‘comodines’ usuales del shell. Por
   ejemplo, si tienes dos directorios para los que deseas un unico fichero
   @f{TAGS}, ingresa @c{etags *.el ../elisp/*.el}, donde @f{../elisp/} es el
   segundo directorio:

   ..example >
     M-x compile RET etags *.el ../elisp/*.el RET
   < example..

   Ingresa

   ..example >
     M-x compile RET etags --help RET
   < example..

   para ver una lista de las opciones aceptadas por @${etags} asi como
   una lista de lenguajes soportados.

   El programa @${etags} maneja más de 20 lenguajes, incluyendo Emacs Lisp,
   Common Lisp, Scheme, C, C++, Ada, Fortran, HTML, Java, LaTeX, Pascal,
   Perl, Postscript, Python, TeX, Texinfo, makefiles, y la mayoría de
   ensambladores. El programa no tiene interruptores para especificar el lenguaje;
   reconoce el lenguaje en un fichero de entrada segun su nombre y contenido.

   @${etags} es muy útil cuando estas escribiendo código y quieres referirte a
   funciones que ya has escrito. Simplemente ejecuta de nuevo @${etags} a medida
   que escribas nuevas funciones, para que formen parte del fichero @f{TAGS}.

   Si crees que ya existe un fichero @f{TAGS} apropiado para lo que buscas, pero
   no conoces donde está, puedes usar el programa @${locate} para intentar
   encontrarlo.

   Escribe @k{M-x locate RET TAGS RET} y Emacs listará los nombres de ruta
   completos de todos tus ficheros @f{TAGS}. En mi sistema, este comando muestra
   34 fichero @f{TAGS}. Por otra parte, un sistema ‘vainilla’ instalado
   recientemente no contenía ningun fichero @f{TAGS}.

   Si la tabla de etiquetas que buscas ya ha sido creada, puedes utilizar el
   comando @c{M-x visit-tags-table} para especificarla. De lo contrario, tendras
   que crear la tabla de etiquetas por tí mismo y luego utilizar @c{M-x
   visit-tags-table}.

*** Construyendo Etiquetas en el codigo de Emacs

    El codigo fuente de GNU Emacs vienen con un @f{Makefile} que contiene un comando
    @${etags} sofisticado que crea, recoge, y une tablas de etiquetas con
    todo el codigo de Emacs y coloca la información dentro de un fichero
    @f{TAGS} en el directorio @f{src/}. (El directorio @f{src/} está debajo
    del nivel superior de tu directorio Emacs.)

    Para construir este fichero @f{TAGS}, debes ir al nivel superior del directorio
    con el codigo fuente de Emacs y ejecutar el comando de compilacion @${make
    tags}:

    ..example >
      M-x compile RET make tags RET
    < example..

    (El comando @${make tags} funciona bien con las fuentes de GNU Emacs, asi
    como con algunos otros paquetes de codigo fuente.)

    Para más información, mira @l{emacs.html#Tags Tables<>Tablas de Etiquetas} en @e(El
    Manual de GNU Emacs).

** Repaso

   Aquí hay un breve resumen de algunas de las funciones introducidas recientemente.

   - @c(while) ::

     Evalúa repetidamente el cuerpo de la expresión simpre y cuando el primer
     elemento del cuerpo sea verdadero. Despues devuelve @c{nil}. (La
     expresión se evalua solo por sus efectos secundarios.)

     Por ejemplo:

     ..srci > elisp
       > (let ((foo 2))
       ^   (while (> foo 0)
       ^     (insert (format "foo es %d.\n" foo))
       ^     (setq foo (1- foo))))
       foo es 2.
       foo es 1.
       nil
     < srci..

     (La función @c{insert} inserta sus argumentos en el punto; la función
     @c{format} devuelve una cadena formateada a partir de sus argumentos de la
     misma manera en que @c{message} formatea sus argumentos; @c{\n} produce una nueva
     línea.)

   - @c(re-search-forward) ::

     Busca un patrón, y si se encuentra, mueve el punto al final de la coincidencia.

     Igual que @c{search-forward}, toma cuatro argumentos:

     1. Una expresión regular que especifica el patrón a buscar. (¡Recuerda
        poner comillas alrededor de este argumento!)

     2. Opcionalmente, el límite de la búsqueda.

     3. Opcionalmente, que hacer si la búsqueda falla, devuelve @c{nil} o un
        mensaje de error.

     4. Opcionalmente, cuántas veces se puede repetir la búsqueda; si es
        negativa, la búsqueda va hacia atrás.

   - @c(let*) ::

     Asocia algunas variables localmente a valores particulares, y luego evalúa
     los argumentos restantes, devolviendo el valor del último. Al asociar las
     variables locales, se pueden usan los valores locales de variables
     declaradas anteriormente.

     Por ejemplo:

     ..srci > elisp
       > (let* ((foo 7)
       ^        (bar (* 3 foo)))
       ^   (message "`bar' es %d." bar))
       ‘bar’ es 21.
     < srci..

   - @c(match-beginning) ::

     Devuelve la posición del inicio del texto encontrado por la última
     búsqueda de una expresión regular.

   - @c(looking-at) ::

     Devuelve @c{t} por verdadero si el texto después del punto coincide con el
     argumento, que debería ser una expresión regular.

   - @c(eobp) ::

     Devuelve @c{t} por verdadero si el punto está al final de la parte
     accesible de un búfer. El final de la parte accesible es el final del
     búfer sin reduccion; es el final de la parte reducida en un búfer
     reducido.

** Ejercicios con @c{re-search-forward}

   - Escribe una función para buscar una expresión regular que coincida con dos o más
     líneas en blanco consecutivas.

   - Escribe una función para buscar palabras duplicadas, como ‘el el’. Consulta la
     Seccion @l{emacs.html#Regexps<>Syntax of Regular Expressions} en @e(El Manual de GNU Emacs), para obtener
     información de cómo escribir una regexp (una expresión regular) para que
     coincida con una cadena compuesta de dos mitades idénticas. Puedes idear
     varias regexps; algunas son mejores que otras. La función que
     yo utilizo se describe en un apéndice, junto con varias regexps. Consulta la
     Seccion @l{#Apéndice A: La función @c{el-el}}.

* Conteo: repetición y regexps

  La repetición y la búsqueda de expresiones regulares son poderosas
  herramientas que con frecuencia se usan al escribir código en Emacs
  Lisp. Este capítulo ilustra el uso de búsqueda de expresiones regulares a
  través de la construcción de comandos de conteo de palabras usando bucles
  @c{while} y recursión.

  La distribución de Emacs estándar contiene una función para contar el
  número de líneas dentro de una región.

  Ciertos tipos de escritura piden el conteo de palabras. Por lo tanto, si
  escribes un ensayo, puedes limitarte a 800 palabras; si escribes una novela,
  puedes disciplinarte a escribir 1000 palabras al día. Parece extraño, pero
  durante mucho tiempo, a Emacs le faltó un comando para contar palabras. Quizás
  la gente usaba Emacs principalmente para codificar o documentar cosas que no
  requerian contar las palabras, o quizás se limitaban al comando de conteo de
  palabras del sistema operativo, @${wc}. Alternativamente, las personas pueden
  haber seguido la convención de las editoriales y calcular un conteo de palabras
  dividiendo el número de caracteres de un documento por cinco.

  Hay muchas maneras de implementar un comando para contar palabras. Aquí hay
  algunos ejemplos, que se puede comparar con el comando estándar de Emacs,
  @c{count-words-region}.

** La función @c{count-words-example}

   Un comando de conteo de palabras podría contar palabras en una línea,
   párrafo, región, o búfer. ¿Qué debe cubrir el comando? Se podría diseñar el
   comando para contar el número de palabras en un búfer completo. Sin embargo,
   la tradición en Emacs fomenta la flexibilidad––se puede querer contar solo
   las palabras en una sección, en lugar de en todo un búfer. Así que tiene más
   sentido diseñar el comando para contar el número de palabras en una
   región. Una vez tienes un comando @c{count-words-region}, puedes, si lo
   deseas, contar palabras en un búfer completo marcándolo con @k{C-x h}
   @%c(mark-whole-buffer).

   Es evidente que contar palabras es un acto repetitivo: a partir del
   principio de la región, se cuenta la primer palabra, luego la segunda,
   despues la tercera, y así sucesivamente, hasta llegar al fin de la
   región. Esto significa que el conteo de palabras se ajusta idealmente a la
   recursión o a un bucle @c{while}.

   Primero, implementaremos el comando para contar palabras con un bucle
   @c{while}, luego con recursión. El comando sera, por supuesto, interactivo.

   La plantilla para una definición de función interactiva es, como siempre:

   ..src > elisp
     (defun nombre-de-funcion (lista-de-argumentos)
       "documentacion…"
       (expresion-interactiva…)
       cuerpo…)
   < src..

   Lo que tenemos que hacer es llenar los espacios.

   El nombre de la función debe ser auto-explicativo y similar al nombre ya
   existente @c{count-lines-region}. Esto hace que el nombre sea fácil de
   recordar. @c{count-words-region} es una buena elección. Ya que ese nombre
   ahora se usa para el comando estándar de Emacs para contar palabras,
   nombraremos a nuestra implementación @c{count-words-example}.

   La función cuenta palabras dentro de una región. Esto significa que la lista
   de argumentos debe contener símbolos que esten ligados a las dos posiciones,
   el principio y fin de la región. Estas dos posiciones se pueden llamar
   @'c{inicio} y @'c{fin} respectivamente. La primer línea de la documentación
   deberia ser una solo frase, ya que esto es todo lo que imprimen comandos como
   @c{apropos}. La expresión interactiva tendra la forma @'c{(interactive "r")},
   puesto que esto provoca que Emacs pase el principio y fin de la región a la lista
   de argumentos de la función. Todo esto es rutina.

   El cuerpo de la función necesita ser escrito para hacer tres tareas:
   primero, configurar condiciones bajo las cuales el bucle @c{while} pueda
   contar palabras, segundo, ejecutar el bucle @c{while}, y tercero, enviar
   un mensaje al usuario.

   Cuando un usuario llama a @c{count-words-example}, el punto puede estar al
   principio o fin de la región. Sin embargo, el proceso de conteo debe empezar
   al principio de la región. Esto significa que querremos poner el punto hay si
   no lo esta. Ejecutando @c{(goto-char beginning)} aseguramos esto. Por
   supuesto, querremos devolver el punto a su posición esperada cuando la
   función termine su trabajo. Por esta razón, el cuerpo debe estar encerrado en
   una expresión @c{save-excursion}.

   La parte central del cuerpo de la función consiste en un bucle @c{while}
   en el que una expresión salta el punto hacia adelante palabra por palabra,
   y otra expresión cuenta estos saltos. Si la prueba-verdadero-o-falso del
   bucle @c{while} es verdadera, el punto salta hacia adelante, y si es
   falsa el punto estaría al final de la región.

   Podríamos usar @c{(forward-word 1)} como la expresión para mover
   el punto hacia adelante palabra por palabra, pero es mas fácil ver lo que
   Emacs identifica como una ‘palabra’ si usamos una búsqueda de expresión
   regular.

   Una busqueda de expresión regular que encuentra el patron que esta buscando,
   deja el punto justo después del último carácter de la coincidencia. Esto
   significa que una sucesión de busquedas exitosas movera el punto hacia
   adelante palabra por palabra.

   Como cuestion práctica, queremos que la busqueda de expresiónes regulares
   salta a través de los espacios en blanco y tambien sobre la puntuacion entre
   palabras. Una regexp que no pueda saltar a través de espacios en blanco entre
   palabras ¡nunca saltara más de una palabra!. Esto significa que la regexp
   debe incluir el espacio en blanco y los signos de puntuación que siguen a una
   palabra, si la hay, asi como la palabra misma. (Una palabra puede terminar un
   búfer y no tener ninguna puntuacion o espacio en blanco, por lo que esa parte de
   la regexp debe ser opcional.)

   Por lo tanto, queremos que el patron de la regexp defina uno o más caracteres
   constituyentes de la palabra, seguidos opcionalmente, por uno o más
   caracteres que no sean constituyentes de la palabra. La expresión regular
   para esto es:

   ..example >
     \w+\W*
   < example..

   La tabla sintactica del búfer determina qué caracteres son o no
   constituyentes de palabras. Para más información sobre la sintaxis, Consulta la
   Sección @l{elisp.html#Syntax Tables<>Tablas de Sintaxis} en @e(El Manual de
   Referencia de GNU Emacs Lisp).

   La expresión se parece a esto:

   ..src > elisp
     (re-search-forward "\\w+\\W*")
   < src..

   (Observa las barras invertidas que preceden a @'c{w} y @'c{W}. Una barra
   invertida tiene un significado especial para el intérprete Emacs Lisp. Indica
   que el siguiente caracter se interpreta de forma diferente a lo habitual. Por
   ejemplo, los dos caracteres, @'c{\n}, representan una @'{nueva línea}, en
   lugar de una barra invertida seguida por @'c{n}. Dos barras invertidas
   consecutivas representan una ‘barra invertida ordinaria’, así que el
   interprete de Emacs Lisp termina viendo una sola barra invertida seguida de
   una letra. Así descubre que la letra es especial.)

   Necesitamon un contador para contar cuántas palabras hay; esta variable debe
   ponerse primero a 0 y luego incrementarse cada vez que Emacs recorra el bucle
   @c{while}. La expresión de incremento es simple:

   ..src > elisp
     (setq cuenta (1+ cuenta))
   < src..

   Finalmente, necesitamos informar al usuario cuántas palabras hay en la
   región. La función @c{message} sirve para presentar este tipo de información al
   usuario. El mensaje tiene que estar redactado de manera que se lea
   correctamente independientemente de cuantas palabras haya en la región: no
   queremos decir que “hay 1 palabras en la región”. El conflicto entre
   singular y plural no es gramatical. Se puede resolver este problema usando
   una expresión condicional que evalue diferentes mensajes dependiendo del
   número de palabras en la región. Hay tres posibilidades: niguna palabra en la
   región, una palabra en la región, y más de una palabra. Esto significa que
   la forma especial @c{cond} es apropiada.

   Todo esto lleva a la siguiente definición de función:

   ..src > elisp
     ;;; ¡Primer versión; tiene errores!
     (defun count-words-example (inicio fin)
       "Imprime el número de palabras en la región.
     Las palabras se definen como al menos un caracter
     constituyente de palabras seguido por al menos un
     caracter no constituyente de palabras. La tabla de
     sintaxis del búfer determina qué caracteres son."
       (interactive "r")
       (message "Contando palaras en la región ... ")

     ;;; 1. Establecer las condiciones apropiadas.
       (save-excursion
         (goto-char inicio)
         (let ((cuenta 0))

     ;;; 2. Ejecutar el bucle while.
           (while (< (point) fin)
             (re-search-forward "\\w+\\W*")
             (setq cuenta (1+ cuenta)))

     ;;; 3. Enviar un mensaje al usuario.
           (cond ((zerop cuenta)
                  (message
                   "La región NO tiene palabras."))
                 ((= 1 cuenta)
                  (message
                   "La región tiene 1 palabra."))
                 (t
                  (message
                   "La región tiene %d palabras." cuenta))))))
   < src..

   Como esta escrito, la función funciona, pero no en todas las circunstancias.

*** El error de espacio en blanco en @c{count-words-example}

    El comando @c{count-words-example} descrito en la sección anterior tiene
    dos errores, o mas bien, un error con dos manifestaciones. Primero, si se
    marca una región que contiene solo espacios en blanco en el medio de algún
    texto el comando @c{count-words-example} dira que la región contiene una
    palabra. Segundo, si se marca una región conteniendo solo espacios en
    blanco al final del búfer o la porción accesible de un búfer reducido,
    el comando muestra un mensaje de error que tiene el siguiente aspecto:

    ..example > elisp
      Search failed: "\\w+\\W*"
    < example..

    Si estás leyendo esto en GNU Emacs, puedes probar estos errores por ti
    mismo.

    Primero, evalúa la función de la manera habitual para instalarla.

    Si quieres, también puedes vincular la funcion al atajo @k(C-c =) evaluando
    lo siguiente:

    ..src > elisp
      (global-set-key "\C-c=" 'count-words-example)
    < src..

    Para realizar la primer prueba, establece la marca y punto al principio y
    fin de la siguiente línea y luego presiona @k{C-c =} (o @k{M-x
    count-words-example} si no se vinculo a @k{C-c =}):

    ..example >
          uno   dos  tres
    < example..

    Emacs te dira, correctamente, que la región tiene tres palabras.

    Repite la prueba, pero coloca la marca al principio de la línea y el punto
    justo @e{antes} de la palabra @'{uno}. De nuevo presiona @k{C-c =} (o @k{M-x
    count-words-example}). Emacs deberia decir que la región no tiene palabras,
    ya que está compuesta solo por espacios en blanco al inicio de la
    línea. ¡Pero en vez de eso, Emacs informa que la región tiene una palabra!

    Para la tercer prueba, copia la línea de ejemplo al final del búfer
    @f{*scratch*} y luego escribe varios espacios al fin de la
    línea. Coloca la marca justo después de la palabra @'{tres} y
    el punto al fin de la línea. (El fin de la línea será el fin del búfer.)
    Como anteriormente, pulsa @k{C-c =} (o @k{M-x count-words-example}). De
    nuevo, Emacs deberia decir que la región no tiene palabras, ya que
    está compuesta solo por espacios en blanco al final de la línea. En
    su lugar, Emacs muestra un mensaje de error diciendo @'{Search failed}.

    Los dos errores provienen del mismo problema.

    Considera la primer manifestación del error, en la que el comando informa
    que el espacio en blanco al principio de la línea contiene una palabra. Lo
    que ocurre es lo siguiente: El comando @c{M-x count-words-example} mueve el
    punto al principio de la región. La prueba de @c{while} que verifica que el
    valor del punto sea más pequeño que el valor de @c{fin}, es verdadera. En
    consecuencia, la busqueda regexp busca y encuentra la primera palabra. Eso
    deja el punto después de la palabra. @c{count} se establece a uno. El bucle
    @c{while} se repite; pero esta vez el valor del punto es mayor al valor de
    @c{fin}, el bucle termina; y la función muestra un mensaje diciendo que el
    número de palabras en la región es uno. En resumen, la expresión regular
    busca y encuentra la palabra aunque esté fuera de la región marcada.

    En la segunda manifestación del error, la región es un espacio en blanco al
    final del búfer. Emacs dice @'{Search failed}. Lo que ocurre es que la
    prueba-verdadero-o-falso en el bucle @c{while} es verdadera, por lo que se
    ejecuta la expresión de búsqueda. Pero como no hay más palabras en el
    buffer, la búsqueda falla.

    En ambas manifestaciones del error, la búsqueda se extiende o intenta
    extenderse fuera de la región.

    La solución es limitar la búsqueda a la región––esta es una acción bastante
    simple, pero como se puede esperar, no es tan simple como se podría
    pensar.

    Como hemos visto, la función @c{re-search-forward} toma un patrón de
    búsqueda como su primer argumento. Pero además de este primer, argumento
    obligatorio, acepta tres argumentos opcionales. El segundo argumento
    opcional limita la búsqueda. El tercer argumento opcional, si es @c{t}, hace
    que la función devuelva @c{nil} en lugar de la señal de error si la búsqueda
    falla. El cuarto argumento opcional es un contador de repeticiones. (En
    Emacs, se puede ver la documentación de una la función pulsando @k{C-h f},
    seguido por el nombre de la función, y finalmente presionando @k{RET}.)

    En la definición de @c{count-words-example}, el valor del fin de la región se
    almacena en la variable @c{fin} que se pasa como un argumento a la
    función. De este modo, podemos añadir @c{fin} como argumento en la
    búsqueda de la expresión regular:

    ..src > elisp
      (re-search-forward "\\w+\\W*" fin)
    < src..

    Sin embargo, con solo este cambio en la definición de
    @c{count-words-example} y luego de probar la nueva versión en una region de
    espacios en blanco, se recibirá un mensaje de error @'{Search failed}.

    Lo que ocurre es esto: la búsqueda se limita a la región, y falla como se
    espera porque no hay caracteres constitutivos de palabras en la
    región. Puesto que falla, se recibe un mensaje de error. Pero no
    queremos recibir un mensaje de error en este caso; queremos recibir el
    mensaje de que "La región no tiene palabras".

    La solución a este problema es proveer un tercer argumento @c{t} a
    @c{re-search-forward}, haciendo que la función regrese @c{nil} en lugar
    de señalar un error si la búsqueda falla.

    Sin embargo, aun con este cambio, veremos el mensaje “Contando palaras en la
    región ... ” y … lo seguiremos viendo …, hasta presionar @k{C-g}
    @%c(keyboard-quit).

    Esto es lo que ocurre: la búsqueda se limitada a la región, como antes, y
    falla porque no hay caracteres constituyentes de palabras en la región, como
    se esperaba. Por consiguiente, la expresión @c{re-search-forward} devuelve
    @c{nil}. No hace nada más. En particular, no mueve el punto, cosa que hace
    como un efecto secundario si encuentra el objetivo de la búsqueda. Después
    de que la expresión @c{re-search-forward} devuelve @c{nil}, se evalua la
    siguiente expresión en el bucle @c{while}. Esta expresión incrementa el
    contador. Entonces el bucle se repite. La prueba-verdadero-o-falso es
    verdadera porque el valor del punto aun es menor al valor del final, ya que
    la expresión @c{re-search-forward} no movio el punto. … y el ciclo repite …

    La definición de @c{count-words-example} requiere otra modificación para
    hacer que la prueba-verdadero-o-falso del bucle @c{while} sea falsa si la
    búsqueda falla. Dicho de otra manera, hay dos condiciones que deben
    cumplirse en la prueba-verdadero-o-falso antes de incrementar la variable de
    conteo: el punto debe estar dentro de la región y la expresión de búsqueda
    debe haber encontrado una palabra para contar.

    Dado que ambas condiciones deben ser ciertas a la vez, la prueba de la
    región y la expresión de búsqueda, pueden unirse con una forma especial
    @c{and} e incrustarse en el bucle @c{while} como la prueba-verdadero-o-falso,
    asi:

    ..src > elisp
      (and (< (point) fin) (re-search-forward "\\w+\\W*" fin t))
    < src..

    (Para obtener mas información sobre @c{and}, consulta la Seccion @l{#La función @c{kill-new}}.)

    La expresión @c{re-search-forward} devuelve @c{t} si la búsqueda tiene exito
    y, como efecto secundario, mueve el punto. En consecuencia, a medida que se
    encuentran las palabras, el punto se mueve a través de la región. Cuando la
    expresion de búsqueda no encuentra otra palabra, o cuando el punto llega al
    final de la región, la prueba-verdadero-o-falso da falso, termina el bucle
    @c{while}, y la función @c{count-words-example} muestra uno u otro de
    sus mensajes.

    Después de incorporar estos cambios finales, @c{count-words-example}
    funciona sin errores (¡o al menos, sin los errores que he
    encontrado!

    ..src > elisp
      ;;; Versión final: while
      (defun count-words-example (inicio fin)
        "Imprime número de palabras en la región."
        (interactive "r")
        (message "Contando palabras en la región ... ")

      ;;; 1. Establecer las condiciones apropiadas.
        (save-excursion
          (let ((cuenta 0))
            (goto-char inicio)

      ;;; 2. Ejecutar el bucle while
            (while (and (< (point) fin)
                        (re-search-forward "\\w+\\W*" fin t))
              (setq cuenta (1+ cuenta)))

      ;;; 3. Enviar un mensaje al usuario.
            (cond ((zerop cuenta)
                   (message
                    "La región NO tiene palabras."))
                  ((= 1 cuenta)
                   (message
                    "La región tiene 1 palabra."))
                  (t
                   (message
                    "La región tiene %d palabras." cuenta))))))
    < src..

** Contar Palabras Recursivamente

   Puedes escribir la función para contar palabras tanto de manera
   recursiva como con un bucle @c{while}. Veamos cómo se hace esto.

   En primer lugar, debemos reconocer que la función @c{count-words-example}
   tiene tres trabajos: establecer las condiciones apropiadas para que ocurra el
   conteo; contar las palabras en la región; y enviar un mensaje al usuario
   diciendo cuántas palabras hay.

   Si escribimos una sola función recursiva para hacer todo, recibiremos un
   mensaje por cada llamada recursiva. Si la región contiene 13 palabras,
   recibiremos trece mensajes, uno tras otro. ¡No queremos esto!. En su lugar,
   debemos escribir dos funciones para hacer el trabajo, una de las cuales (la función
   recursiva) se utilizara dentro de la otra. Una función configurará las
   condiciones y mostrara el mensaje; la otra devolverá el conteo de palabras.

   Comencemos con la función que hace que se muestre el mensaje. Podemos
   continuar llamandola @c{count-words-example}.

   Esta es la función que el usuario llamara. Será interactiva. De hecho,
   será similar a nuestras versiones previas de esta función, excepto que
   llamará a @c{contar-palabras-recursivamente} para determinar cuántas palabras hay en
   la región.

   Podemos construir facilmente una plantilla para esta función, basada en
   versiones anteriores:

   ..src > elisp
     ;; Versión Recursiva; usa búsqueda de expresiónes regulares
     (defun count-words-example (inicio fin)
       "documentacion…"
       (expresion-interactiva…)

     ;;; 1. Establecer las condiciones apropiadas.
       (mensaje explicativo)
       (funciones de configuracion…

     ;;; 2. Contar las palabras.
         llamada recursiva

     ;;; 3. Envía un mensaje al usuario.
         mensaje que proporciona el conteo de palabras))
   < src..

   La definición parece sencilla, excepto que de alguna manera el conteo
   devuelto por la llamada recursiva debe ser pasado al mensaje que muestra el
   conteo de palabras. Un poco de reflexion sugiere que esto se puede hacer
   mediante una expresión @c{let}: podemos enlazar una variable en la lista de
   variables de la expresion @c{let} con el número de palabras de la región, tal y
   como lo devuelve la llamada recursiva; y entonces la expresión @c{cond}, podra
   mostrar el valor al usuario.

   Con frecuencia, uno piensa que el enlace dentro de una expresión @c{let} es
   algo secundario al trabajo ‘primario’ de una función. Pero en este caso,
   se podría considerar que el trabajo ‘primario’ de la función (contar
   palabras), ocurre dentro de la expresión @c{let}.

   Usando @c{let}, la definición de función se veria asi:

   ..src > elisp
     (defun count-words-example (inicio fin)
       "Imprime número de palabras en la región."
       (interactive "r")

     ;;; 1. Establecer las condiciones apropiadas.
       (message "Contando palabras en la región ... ")
       (save-excursion
           (goto-char inicio)

     ;;; 2. Contar las palabras.
         (let ((cuenta (contar-palabras-recursivamente fin)))

     ;;; 3. Enviar un mensaje al usuario.
           (cond ((zerop cuenta)
                  (message
                   "La región NO tiene palabras."))
                 ((= 1 cuenta)
                  (message
                   "La región tiene 1 palabra."))
                 (t
                  (message
                   "La región tiene %d palabras." cuenta))))))
   < src..

   A continuacion, tenemos que escribir la función de conteo recursivo.

   Una función recursiva tiene al menos tres partes: la ‘prueba-hazlo-de-nuevo’, la
   ‘expresion-del-siguiente-paso’, y la llamada recursiva.

   La prueba-hazlo-de-nuevo determina si la función será o no llamada de
   nuevo. Ya que estamos contando palabras en una región y podemos usar una
   función que mueve el punto hacia delante para cada palabra, la
   prueba-hazlo-de-nuevo puede evaluar si el punto todavía está dentro de la
   región. La prueba-hazlo-de-nuevo debe encontrar el valor del punto y
   determina si el punto está antes, en, o después del valor del final de la
   región. Podemos usar la función @c{point} para localizar el punto.
   Claramente, se debe pasar el valor del final de la región como un argumento a
   la función de conteo recursivo.

   Además, la prueba-hazlo-de-nuevo también tiene que probar si la búsqueda encuentra una
   palabra. Si no lo hace, la función no deberia llamarse de nuevo.

   La expresion-del-siguiente-paso cambia un valor de modo que cuando se
   supone que la función recursiva deja de llamarse así misma, se detiene. Más
   precisamente, la expresion-del-siguiente-paso cambia un valor
   en el momento adecuado, la prueba-hazlo-de-nuevo detiene la función recursiva de
   llamarse a si misma otra vez. En este caso, la expresion-del-siguiente-paso
   puede ser la expresión que mueve el punto hacia adelante, palabra por
   palabra.

   La tercera parte de una función recursiva es la llamada recursiva.

   En algún lugar, también, necesitamos una parte que haga el ‘trabajo’ de la
   función, una parte que haga el conteo. ¡Una parte vital!

   Pero ya tenemos un esquema de la función de conteo recursivo:

   ..src > elisp
     (defun contar-palabras-recursivamente (fin-de-region)
       "documentacion…"
       prueba-hazlo-de-nuevo
       expresion-del-siguiente-paso
       llamada recursiva)
   < src..

   Ahora tenemos que rellenar los huecos. Comencemos con los casos más simples:
   si el punto esta en o mas alla del fin de la región, no puede haber ninguna
   palabra en la región, así que la función deberia regresar cero. Del mismo
   modo, si la búsqueda falla no hay mas palabras para contar, por lo que la función
   tambien deberia regresar cero.

   Por otro lado, si el punto esta dentro de la región y la búsqueda tiene éxito, la
   función deberia volver a llamarse a si misma.

   Por lo tanto, la prueba-hazlo-de-nuevo se vería así:

   ..src > elisp
     (and (< (point) fin-de-region)
          (re-search-forward "\\w+\\W*" fin-de-region t))
   < src..

   Ten en cuenta que la expresión de búsqueda es parte de la prueba-hazlo-de-nuevo––la
   función devuelve @c{t} si su búsqueda tiene éxito y @c{nil} si
   falla. (Consulta la Seccion @l{#El error de espacio en blanco en @c{count-words-example}},
   para una explicación de cómo funciona @c{re-search-forward}.)

   La prueba-hazlo-de-nuevo es la prueba verdadero-o-falso de una cláusula
   @c{if}. Claramente si la prueba-hazlo-de-nuevo tiene éxito, la parte-then de la
   cláusula @c{if} llamaría a la función de nuevo; pero si falla, la parte-else
   deveria regresar cero ya que está fuera de la región o la búsqueda
   falló porque no había palabras que encontrar.

   Pero antes de considerar la llamada recursiva, se necesita considerar la
   expresion-del-siguiente-paso. ¿Qué es esto? Curiosamente, es la parte
   de la búsqueda de la prueba-hazlo-de-nuevo.

   Además de regresar @c{t} o @c{nil} en la prueba-hazlo-de-nuevo,
   @c{re-search-forward} mueve el punto hacia adelante como un efecto secundario
   de una búsqueda exitosa. Esta es la acción que cambia el valor de punto
   para que la función recursiva deje de llamarse a sí misma cuando el punto
   complete su movimiento a través de la región. Por consiguiente, la
   expresión @c{re-search-forward} es la expresion-del-siguiente-paso.

   Entonces, en la plantilla, el cuerpo de la función @c{contar-palabras-recursivamente} se
   ve asi:

   ..src > elisp
     (if prueba-hazlo-de-nuevo-y-del-siguiente-paso-combinadas
         ;; then
         llamada-recursiva-regresando-la-cuenta
       ;; else
       regresar-cero)
   < src..

   ¿Cómo incorporar el mecanismo que cuenta?

   Si no estás acostumbrado a escribir funciones recursivas, una pregunta
   como esta puede ser un problema. Pero puede y debe abordarse
   sistemáticamente.

   Sabemos que el mecanismo de conteo debe estar asociado de algúna manera con
   la llamada recursiva. De hecho, dado que la expresion-del-siguiente-paso
   mueve el punto hacia adelante en una palabra, y dado que se hace una llamada
   recursiva para cada palabra, el mecanismo de conteo debe ser una expresión
   que agregue uno al valor devuelto en una llamada a @c{contar-palabras-recursivamente}

   Considera varios casos:

   - Si hay dos palabras en la región, la función debe devolver un valor
     resultante de sumar uno al valor devuelto al contar la primera palabra, más
     el número devuelto al contar las palabras restantes en la región, que en
     este caso es uno.

   - Si hay una palabra en la región, la función devolvería un valor
     que resulte de sumar uno al valor devuelto cuando cuenta esa
     palabra, más el número devuelto cuando cuenta las palabras restantes
     en la región, que en este caso es cero.

   - Si no hay palabras en la región, la función deberia regresar cero.


   En el esquema podemos ver que la parte-else del @c{if} devuelve cero
   para el caso en el que no hay palabras. Esto significa que la parte-then
   del @c{if} debe devolver un valor resultante de sumar uno al valor
   devuelto por el conteo las palabras restantes.

   La expresión se vera asi, donde @c{1+} es una función que añade uno a
   su argumento.

   ..src > elisp
     (1+ (contar-palabras-recursivamente fin-de-region))
   < src..

   La función @c(contar-palabras-recursivamente) completa se vera asi:

   ..src > elisp
     (defun contar-palabras-recursivamente (fin-de-region)
       "documentacion…"

     ;;; 1. prueba-hazlo-de-nuevo
       (if (and (< (point) fin-de-region)
                (re-search-forward "\\w+\\W*" fin-de-region t))

     ;;; 2. parte-then: la llamada recursiva
           (1+ (contar-palabras-recursivamente fin-de-region))

     ;;; 3. parte-else
         0))
   < src..

   Examinemos como funciona esto:

   Si no hay palabras en la región, la parte-else de la expresión @c{if} es
   evaluada y, por tanto, la función devuelve cero.

   Si hay una palabra en la región, el valor del punto es menor que el valor
   de @c{fin-de-region} y la búsqueda tiene éxito. En este caso, la
   prueba-verdadero-o-falso de la expresión @c{if} es verdadera, y se evalua
   la parte-then de la expresión @c{if}. Se evalua la expresión de conteo.
   Esta expresión devuelve un valor (que será el valor devuelto por
   toda la función) que es la suma de uno añadida al valor devuelto por
   una llamada recursiva.

   Mientras tanto, la expresion-del-siguiente-paso ha hecho que punto salte
   sobre la primera (y en este caso única) palabra en la región. Esto significa
   que cuando @c{(contar-palabras-recursivamente fin-de-region)} se evalua una
   segunda vez, como resultado de la llamada recursiva, el valor del punto será
   igual o mayor que el valor del fin de región. Así que esta vez,
   @c{contar-palabras-recursivamente} devolverá cero. El cero se sumara a uno, y
   la evaluación original de @c{contar-palabras-recursivamente} devolverá uno
   más cero, que es uno y es la cantidad correcta.

   Claramente, si hay dos palabras en la región, la primer llamada a
   @c{contar-palabras-recursivamente} devuelve uno mas el valor devuelto por
   @c{contar-palabras-recursivamente} en una región que contiene la palabra
   restante––es decir, suma uno a uno, produciendo dos, que es la
   cantidad correcta.

   De manera similar, si hay tres palabras en la región, la primer llamada
   @c{contar-palabras-recursivamente} devuelve uno mas el valor devuelto de
   @c{contar-palabras-recursivamente} en una región que contiene las dos
   palabras restantes––y así sucesivamente.

   Con la documentación completa las dos funciones serian asi:

   La función recursiva:

   ..src > elisp
     (defun contar-palabras-recursivamente (fin-de-region)
       "Número de palabras entre punto y FIN-DE-REGION."

     ;;; 1. prueba-hazlo-de-nuevo
       (if (and (< (point) fin-de-region)
                (re-search-forward "\\w+\\W*" fin-de-region t))

     ;;; 2. parte-then: la llamada recursiva
           (1+ (contar-palabras-recursivamente fin-de-region))

     ;;; 3. parte-else
         0))
   < src..

   El envoltorio:

   ..src > elisp
     ;;; Versión Recursiva
     (defun count-words-example (inicio fin)
       "Imprime número de palabras en la región.

     Las palabras se definen como al menos un caracter
     constituyente de palabras seguido por al menos un
     caracter no constituyente de palabras. La tabla de
     sintaxis del búfer determina qué caracteres son."
       (interactive "r")
       (message "Contando palabras en la región ... ")
       (save-excursion
           (goto-char inicio)
         (let ((cuenta (contar-palabras-recursivamente fin)))
           (cond ((zerop cuenta)
                  (message
                   "La región NO tiene palabras."))
                 ((= 1 cuenta)
                  (message "La región tiene 1 palabra."))
                 (t
                  (message
                   "La región tiene %d palabras." cuenta))))))
   < src..

** Ejercicio: Conteo de signos de puntuación

   Usando un bucle @c{while}, escribe una función para contar el número de
   signos de puntuación en una región––punto, coma, punto y coma, dos
   puntos, signos de interrogacion y exclamación. Has lo mismo usando
   recursión.

* Contando palabras en una @c{defun}

  Nuestro siguiente proyecto es contar el número de palabras en una definición
  de función. Claramente, esto se puede hacer usando alguna variante de
  @c{count-words-example}. Consulta la Seccion @l{#Conteo: repetición y regexps}.
  Si solo vamos a contar las palabras en una definición, es bastante fácil
  marcar la definición con el comando @k{C-M-h} @%c(mark-defun), y luego llamar
  a @c{count-words-example}.

  Sin embargo, soy más ambicioso: quiero contar las palabras y símbolos en
  todas las definiciónes del codigo de Emacs y despues imprimir un grafico que
  muestre cuántas funciones hay de cada tamaño: cuántas contienen de 40 a 49
  palabras o símbolos, cuántas contienen de 50 a 59 palabras o símbolos, y
  así sucesivamente. A menudo he tenido curiosidad por saber cuanto abarca una
  función típica, y esto lo dira.

  Descrito en una frase, el proyecto del histograma es desalentador; pero dividido
  en muchos pequeños pasos, dando uno a uno a la vez, el proyecto se vuelve
  menos atemorizante. Consideremos cuales deberian ser los pasos a seguir:

  - Primero, escribir una función para contar las palabras en una
    definición. Esto incluye el problema de manejar tanto símbolos como
    palabras.

  - Segundo, escribir una función para listar el número de palabras de cada
    función en un fichero. Esta función puede usar la función
    @c{count-words-in-defun}.

  - Tercero, escribir una función para listar el número de palabras en cada
    función en cada uno de los ficheros. Esto implica encontrar automáticamente
    los diferentes ficheros, cambiar entre ellos, y contar las palabras en las
    definiciones dentro de cada uno.

  - Cuarto, escribir una función para convertir la lista de números que
    creamos en el paso tres a un formulario que sea adecuado para
    imprimir en forma de grafico.

  - Quinto, escribir una función para imprimir los resultados como un grafico.


  ¡Este es un gran proyecto! Pero si tomamos cada paso lentamente, no será
  difícil.

** ¿Qué contar?

   Cuando empezamos a pensar en como contar las palabras
   en una definición de función, la primera pregunta es (o deberia ser) ¿qué
   vamos a contar?  Cuando hablamos de ‘palabras’ con repecto a una
   definición de función Lisp, en realidad estamos hablando, en gran parte, de
   ‘símbolos’. Por ejemplo, la siguiente función @c{multiplicar-por-siete}
   contiene los cinco símbolos @c{defun}, @c{multiplicar-por-siete}, @c{numero},
   @c{*}, y @c{7}. Además, en la cadena de documentación, contiene cuatro
   palabras @'{Multiplicar}, @'{NUMERO}, @'{por}, y @'{siete}. El símbolo
   @'{número} se repite, por lo que la definición contiene un total de diez
   palabras y símbolos.

   ..src > elisp
     (defun multiplicar-por-siete (numero)
       "Multiplica NUMERO por siete."
       (* 7 numero))
   < src..

   Sin embargo, si marcamos la definición @c{multiplicar-por-siete} con @k{C-M-h}
   @%c{mark-defun}, y luego llamamos a @c{count-words-example} en ella,
   encontraremos que @c{count-words-example} afirma que la definición tiene once
   palabras, no diez ¡Alguna cosa está mal!

   El problema es doble: @c{count-words-example} no cuenta el @'{*} como una
   palabra, y cuenta el símbolo unico, @c{multiplicar-por-siete},
   conteniendo tres palabras. Los guines se tratan como si fueran
   espacios entre palabras en lugar de conectores entre palabras
   @'{multiplicar-por-siete} se cuenta como si fuese escrito
   @'{multiplicar por siete}.

   La causa de esta confusión es la expresión regular que busca la definición
   @c{count-words-example} que mueve el punto hacia adelante palabra por
   palabra. En la versión canónica de @c{count-words-example}, la regexp es:

   ..example >
     "\\w+\\W*"
   < example..

   Esta expresión regular es un patrón que define uno o más caracteres
   constituyentes de palabras, posiblemente seguidos por uno o más caracteres
   que no son constituyentes de palabras. Lo que se entiende por ‘caracteres
   constituyentes de palabras’ nos lleva a la cuestión de la sintaxis, que merece
   una sección en por sí misma.

** ¿Qué constituye una palabra o símbolo?

   Emacs trata diferentes caracteres como pertenecientes a diferentes
   @:{categorías sintacticas}. Por ejemplo, la expresión regular, @'{\\w+}, es
   un patrón que especifica uno o más caracteres @e{constituyentes de
   palabras}. Los caracteres constituyentes de palabras son miembros de una
   categoría sintactica. Otras categoría sintactica incluye la clase de
   caracteres de puntuación, como el punto y la coma, y la clase de caracteres
   de espacio en blanco, como el espacio en blanco o el tabulador. (Para más
   información, consulta la Seccion @l{elisp.html#Syntax Tables<>Tablas de Sintaxis} en @e(El
   Manual de Referencia GNU Emacs Lisp).)

   Las tablas sintacticas especifican qué caracteres pertenecen a qué
   categorías. Normalmente un guión no está especificado como un ‘caracter
   constiyente de una palabra’. En su lugar, se especifica como perteneciente a
   la ‘clase de caracteres que son parte de los nombres de símbolos, pero no de
   las palabras’.  Esto significa que la función @c{count-words-example} la
   trata del mismo modo que trata un espacio en blanco entre palabras, por lo
   qué la funcion @c{count-words-example} cuenta a @'{multiplicar-por-siete} como
   tres palabras.

   Hay dos maneras de hacer que Emacs cuente @'{multiplicar-por-siete} como un
   símbolo: modificar la tabla sintactica o modificar la expresión regular.

   Se podría redefinir un guión como un caracter constituyente
   de una palabra modificando la tabla de sintaxis que Emacs guarda para cada
   modo. Esta acción serviría a nuestro propósito, excepto que un guion es
   simplemente el caracter más común dentro de los símbolos que no es son tipicamente un
   caracter constituyente de una palabra; hay otros, también.

   Alternativamente, podemos redefinir la regexp usada en la definición
   de @c{count-words-example} para incluir símbolos. Este procedimiento tiene el mérito
   de la claridad, pero la tarea es un poco dificil.

   La primera parte es bastante simple: el patrón debe coincidir con “al
   menos un carácter que sea una palabra o un símbolo constituyente”. Asi:

   ..example >
     "\\(\\w\\|\\s_\\)+"
   < example..

   El @'c{\\(} es la primera parte del constructor de agrupacion que incluye el
   @'c{\\w} y el @'c{\\s_} como alternativas, separadas por @'c{\\|}. El @'c{\\w}
   coincide con cualquier caracter constituyente de una palabras y @'c{\\s_} con
   cualquier caracter que forme parte de un símbolo no constituyente de
   palabras. El signo @'c{+} a continuacion de la agrupacion indica que los caracteres que
   componen la palabra o el símbolo deben coincidir al menos una vez.

   Sin embargo, la segunda parte de la regexp es más difícil de diseñar. Lo que
   queremos es seguir la primera parte con “opcionalmente uno o más
   caracteres que no constituyen una palabra o símbolo”. Al principio, pense
   que esto se podría definir con lo siguiente:

   ..example >
     "\\(\\W\\|\\S_\\)*"
   < example..

   Las mayúsculas @'c{W} y @'c{S} coinciden con caracteres que @e{no} son
   parte de palabras o símbolos. Desafortunadamente, esta expresión
   coincide con cualquier caracter que no sea parte de una palabra o simbolo.
   ¡Esto coincide con cualquier caracter!

   Entonces note que cada palabra o símbolo en mi región de prueba iba
   seguido de un espacio en blanco (espacio en blanco, tabulador, o línea
   nueva). Así que intente colocar un patrón para que coincidiese con uno o más espacios
   en blanco después del patrón para una o más palabras o símbolos
   constituyentes. Esto tambien falló. Las palabras y los símbolos suelen
   estar separados por espacios en blanco, pero en el código real los
   paréntesis pueden ir despues de los símbolos y la puntuación puede seguir a las
   palabras. Así que finalmente, diseñe un patrón en el que los componentes de
   la palabra o simbolo van seguidos opcionalmente por caracteres que no son
   espacios en blanco, seguidos a su vez por espacios en blanco opcionales.

   Aquí está la expresión regular completa:

   ..example >
     "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*"
   < example..

** La función @c{contar-palabras-en-definicion}

   Hemos visto que hay varias maneras de escribir la función
   @c{count-word-region}. Para escribir @c{contar-palabras-en-definicion},
   basta con adaptar una de estas versiones.

   La versión que utiliza un bucle @c{while} es fácil de comprender, así que voy
   a adaptarla. Debido a que @c{contar-palabras-en-definicion} formara parte de
   un programa más complejo, no necesita ser interactivo y ni mostrar un
   mensaje, solamente devolver el conteo. Estas consideraciones simplifican un
   poco la definición.

   Por otro lado, @c{contar-palabras-en-definicion} se utilizara dentro de un
   buffer que contiene definiciones de función. Por consiguiente, es razonable
   pedir que la función determine si se llama cuando el punto está dentro de una
   definición de función, y si lo esta, que devuelva el conteo para esa
   definición. Esto añade complejidad a la definición, pero nos ahorra la
   necesidad de pasar argumentos a la función.

   Estas consideraciones nos llevan a preparar la siguiente plantilla:

   ..src > elisp
     (defun contar-palabras-en-definicion ()
       "documentacion…"
       (configuracion…
          (bucle while…)
        regresar conteo)
   < src..

   Como de costumbre, nuestro trabajo es rellenar los huecos.

   Primero, la configuración.

   Suponemos que esta función se llamara dentro de un búfer que contiene
   definiciones de función. El punto estara o no dentro de una definición de
   función. Para que @c{contar-palabras-en-definicion} funcione, el punto
   debe moverse al principio de la definición, un contador debe empezar en cero,
   y el bucle de conteo debe parar cuando el punto alcance el final de la definición.

   La función @c{beginning-of-defun} busca hacia atrás un delimitador de
   apertura como @'{(} al principio de una línea, y mueve el punto a esa
   posición, o sino al límite de la búsqueda. En la práctica, esto significa
   que @c{beginning-of-defun} mueve el punto al principio de la funcion que lo
   rodea o a la anterior función, o bien al principio del buffer.

   El bucle @c{while} requiere un contador para registrar las palabras o
   símbolos que se estan contando. Una expresión @c{let} puede ser usada para
   crear una variable local para este propósito, y vincularse a un valor inicial
   de cero.

   La función @c{end-of-defun} opera como @c{beginning-of-defun} excepto
   que mueve el punto al fin de la definición. @c{end-of-defun} puede usarse
   como parte de una expresión que determina la posición del fin de la
   definición.

   La configuración para @c{contar-palabras-en-definicion} toma forma rápidamente:
   primero movemos el punto al principio de la definición, luego creamos
   una variable local para almacenar el conteo, y finalmente, registramos la
   posición del final de la definición para que el bucle @c{while} sepa cuando
   terminar.

   El código es asi:

   ..src > elisp
     (beginning-of-defun)
     (let ((cuenta 0)
           (fin (save-excursion (end-of-defun) (point))))
   < src..

   El código es simple. Es probable que la única pequeña complicación este en
   @c{fin}, que se vincula a la posición del fin de la definición con una expresión
   @c{save-excursion} que devuelve el valor de @c{end-of-defun} que a su vez
   mueve temporalmente el punto al final de la definición.

   La segunda parte de @c{contar-palabras-en-definicion}, después de la
   configuración, es el bucle @c{while}.

   El bucle debe contener una expresión que mueva el punto hacia adelante
   palabra por palabra y símbolo por símbolo, y otra expresión que cuente los
   saltos. La prueba-verdadero-o-falso del bucle @c{while} debe ser
   verdadero siempre y cuando el punto salte hacia adelante, y falso
   si el punto esta al final de la definición. Ya hemos redefinido la expresión
   regular para esto, así que el bucle es sencillo:

   ..src > elisp
     (while (and (< (point) fin)
                 (re-search-forward
                  "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*" fin t)
       (setq cuenta (1+ cuenta)))
   < src..

   La tercera parte de la definición devuelve el numero de palabras y
   símbolos. Esta parte es la última expresión dentro del cuerpo de la expresión
   @c{let}, y puede ser, simplemente la variable local @c{cuenta}, que al
   evaluarse devuelve el conteo.

   En conjunto, la definición @c{contar-palabras-en-definicion} luce así:

   ..src > elisp
     (defun contar-palabras-en-definicion ()
       "Devuelve el número de palabras y símbolos en una defun."
       (beginning-of-defun)
       (let ((cuenta 0)
             (fin (save-excursion (end-of-defun) (point))))
         (while
             (and (< (point) fin)
                  (re-search-forward
                   "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*"
                   fin t))
           (setq cuenta (1+ cuenta)))
         cuenta))
   < src..

   ¿Cómo probar esto? La función no es interactiva, pero es fácil poner
   un envoltorio alrededor de la función para hacerla interactiva; podemos
   usar casi el mismo código que el de la versión recursiva de
   @c{count-words-example}:

   ..src > elisp
     ;;; Versión Interactiva.
     (defun contar-palabras-en-defun ()
       "Número de palabras y símbolos en una definición de función."
       (interactive)
       (message
        "Contando palabras y símbolos en la definición de función ... ")
       (let ((cuenta (contar-palabras-en-definicion)))
         (cond
          ((zerop cuenta)
           (message
            "La definición NO tiene palabras o símbolos."))
          ((= 1 cuenta)
           (message
            "La definición tiene 1 palabra o símbolo."))
          (t
           (message
            "La definición tiene %d palabras o símbolos." cuenta)))))
   < src..

   Reutilicemos @k{C-c =} como un conveniente atajo:

   ..src > elisp
     (global-set-key "\C-c=" 'contar-palabras-en-defun)
   < src..

   Ahora podemos probar @c{contar-palabras-en-defun}: instala ambas funciones
   @c{contar-palabras-en-definicion} y @c{contar-palabras-en-defun}, y asigna el atajo,
   luego coloca el cursor dentro de la siguiente definición:

   ..src > elisp
     (defun multiplicar-por-siete (numero)
       "Multiplicar NUMERO por siete."
       (* 7 numero))
   < src..

   ¡Éxito! La definición tiene 10 palabras y símbolos.

   El siguiente problema es contar el numero de palabras y símbolos en
   varias definiciones en un mismo fichero.

** Contar varias @c{defuns} dentro de un fichero

   Un fichero como @f{simple.el} puede tener cientos o más definiciones dentro
   de el. Nuestro objetivo a largo plazo es recopilar estadísticas de muchos ficheros,
   pero como primer paso, nuestro objetivo inmediato es recoger estadísticas de
   un solo fichero.

   La información será una serie de números, siendo cada número la longitud de
   una definición de función. Podemos almacenar los números en una lista.

   Sabemos que querremos incorporar la información relativa a un fichero
   con información sobre muchos otros ficheros; esto significa que la
   función para contar la longitudes de las definiciones solo necesita
   devolver la lista de longitudes. No necesita ni debe mostrar ningun mensaje.

   Los comandos de conteo de palabras contienen una expresión para mover el punto
   palabra a palabra y otra expresión para contar los saltos. La función
   para devolver la longitud de las definiciones puede ser diseñada para trabajar
   del mismo modo, con una expresión para mover el punto hacia adelante definición
   por definición y otra expresión para construir la lista de longitudes.

   Esta afirmacion del problema hace que sea elemental escribir la definición de
   función. Claramente, empezaremos el conteo al principio del fichero, por lo
   que el primer comando será @c{(goto-char (point-min))}. Lo siguiente, es
   iniciar el bucle @c{while}; y la puerba verdadero-o-falso del bucle puede ser
   una regexp para la siguiente definición de función––siempre y cuando la
   búsqueda tenga éxito, el punto se movera hacia adelante y luego se evaluara
   el cuerpo del bucle. El cuerpo necesita una expresión que construya la lista
   de longitudes. @c{cons}, el comando de construccion de listas, puede
   utilizarce para crear la lista. Esto es casi todo lo que hay.

   Este fragmento de código tendria el siguiente aspecto:

   ..src > elisp
     (goto-char (point-min))
     (while (re-search-forward "^(defun" nil t)
       (setq lista-de-longitudes
             (cons (contar-palabras-en-definicion) lista-de-longitudes)))
   < src..

   Dejamos fuera el mecanismo para encontrar el fichero que contiene las
   definiciones de función.

   En ejemplos anteriores, usabamos este fichero, o el fichero Info, o cambiamos
   de un búfer a otro, como el búfer @f{*scratch*}.

   Encontrar un fichero es un nuevo proceso que aun no hemos discutido.

** Encontrar un fichero

   Para encontrar un fichero en Emacs, se usa el comando @k{C-x C-f}
   @%c(find-file). Este comando es casi, pero no del todo adecuado para el
   problema de las longitudes.

   Veamos el codigo fuente de @c{find-file}:

   ..src > elisp
     (defun find-file (filename)
       "Edita el fichero FILENAME.
     Cambia a un búfer visitando el fichero FILENAME,
     creando uno si no existe ya."
       (interactive "FFind file: ")
       (switch-to-buffer (find-file-noselect filename)))
   < src..

   (La definición de la versión más reciente de @c{find-file} permite
   especificar comodines especiales para visitar múltiples ficheros; que hacen la
   definición más compleja y no la discutiremos aquí, ya que no es relevante. Se
   puede ver el codigo usando @k{M-.} @%c(find-tag) o @k{C-h f} @%c(describe-function).)

   La definición que estoy mostrando posee una documentación corta, pero
   completa y una expresion interactiva que pide un nombre de fichero
   cuando se usa el comando interactivamente. El cuerpo de la definición
   contiene dos funciones, @c{find-file-noselect} y @c{switch-to-buffer}.

   De acuerdo con su documentación, tal y como se muestra con @k{C-h f} (el comando
   @c{describe-function}), la función @c{find-file-noselect} lee el fichero
   nombrado en un búfer y devuelve el búfer. (Su versión más
   reciente incluye un argumento comodín opcional, así como otro para leer un
   fichero literalmente y otro para suprimir mensajes de advertencia. Estos
   argumentos opcionales son irrelevantes.)

   Sin embargo, la función @c{find-file-noselect} no selecciona el búfer en
   el que se pone el fichero. Emacs no cambia su atención (o la tuya si estás
   usando @c{find-file-noselect}) al búfer seleccionado. Esto es lo que hace
   @c{switch-to-buffer}: cambia el búfer al que se dirige la
   atención de Emacs; y cambia el búfer mostrado en la ventana al nuevo
   búfer. Hemos discutido el cambiando de búfer en otra parte. (Consulta la Seccion
   @l{#Cambiando búfers}.)

   En este proyecto de histograma, no necesitamos mostrar cada fichero en la
   pantalla ya que el programa determina el tamaño de cada definición dentro de
   el. En lugar de emplear @c{switch-to-buffer}, podemos trabajar con
   @c{set-buffer}, que redirige la atención del programa a un búfer diferente,
   pero no lo muestra en pantalla. Así en vez llamar a @c{find-file} para hacer
   el trabajo, debemos escribir nuestra propia expresión.

   La tarea es fácil: usar @c{find-file-noselect} y @c{set-buffer}.

** @c{lista-de-longitudes-en-fichero} en detalle

   El núcleo de la función @c{lista-de-longitudes-en-fichero} es un bucle
   @c{while} que contiene una función para mover el punto hacia delante ‘defun a
   defun’ y una función para contar el número de palabras y símbolos en cada
   definicion de funcion. Este núcleo debe ser rodeado por funciones que
   realizan otras tareas varias, incluyendo encontrar el fichero, y asegurarse
   que el punto empieza al principio del fichero. La definición de la función se
   ve asi:

   ..src > elisp
     (defun lista-de-longitudes-en-fichero (nombre-de-fichero)
       "Devuelve la lista de longitudes de las definiciones dentro de NOMBRE-DE-FICHERO.
     La lista devuelta es una lista de números.
     Cada número es el número de palabras o
     símbolos en una definición."
       (message "Trabajando en `%s' ... " nombre-de-fichero)
       (save-excursion
         (let ((buffer (find-file-noselect nombre-de-fichero))
               (lista-de-longitudes))
           (set-buffer buffer)
           (setq buffer-read-only t)
           (widen)
           (goto-char (point-min))
           (while (re-search-forward "^(defun" nil t)
             (setq lista-de-longitudes
                   (cons (contar-palabras-en-definicion) lista-de-longitudes)))
           (kill-buffer buffer)
           lista-de-longitudes)))
   < src..

   A la función se le pasa un argumento, el nombre del fichero en el que
   trabajará. Tiene cuatro líneas de documentación, pero ninguna especificacion
   interactiva. Ya que a la gente le preocupa que un ordenador se estropee si
   no ve nada, la primera línea del cuerpo es un mensaje de aviso.

   La siguiente línea contiene un @c{save-excursion} que devuelve la atencion de
   Emacs al búfer actual cuando la función se completa. Esto es útil
   en caso de incorporar esta función dentro de otra función que suponga que el punto
   se restaura al búfer original.

   En la varlist de la expresión @c{let}, Emacs busca el fichero y enlaza
   la variable local @c{buffer} al búfer que contiene el fichero. Al mismo
   tiempo, Emacs crea @c{lista-de-longitudes} como una variable local.

   A continuacion, Emacs cambia su atención al búfer.

   En la siguiente línea, Emacs hace que el búfer sea de solo lectura.
   Idealmente, esta línea no es necesaria. Ninguna de las funciones para contar
   palabras y símbolos en una definición de función debe cambiar el búfer.
   Ademas, el búfer no va a guardarse, incluso si se ha modificado. Esta línea
   es enteramente la consecuencia de una gran cautela, quizás excesiva. La razón
   de la precaución es que esta función y aquellas a las que llama trabajaran en
   el codigo fuente de Emacs y es un inconveniente si se modifican de
   forma inadvertida. No hace falta decir que no me di cuenta de la necesidad de
   esta línea hasta que un experimento salio mal y empezó a modificar mis
   ficheros…

   Luego viene una llamada para extender el búfer si esta reducido. Esta función
   normalmente es innecesaria––Emacs crea un búfer nuevo si no existe ninguno;
   pero si hay un búfer visitando el fichero, Emacs devuelve ese búfer. En este
   caso, el búfer puede estar reducido y debe extenderse. Si quisieramos ser
   completamente ‘amigables con el usuario’, nos encargariamos de guardar la
   restricción y la ubicacion del punto, pero no lo haremos.

   La expresión @c{(goto-char (point-min))} mueve el punto al principio del
   búfer.

   Luego viene un bucle @c{while} en el que se realiza el ‘trabajo’ de la
   función. En el bucle, Emacs determina la longitud de cada definición y
   construye una lista de longitudes que contiene la información.

   Emacs mata el búfer después de trabajar a través de el. Esto es para ahorrar
   espacio dentro de Emacs. Mi versión de GNU Emacs 19 contenía 300 ficheros
   de codigo fuente de interés; GNU Emacs 22 contiene mas de mil ficheros de codigo
   fuente. Otra función aplicará @c{lista-de-longitudes-en-fichero} a cada uno de los
   ficheros.

   Finalmente, la última expresión dentro de la expresión @c{let} es la variable
   @c{lista-de-longitudes}; su valor se devuelve como el valor de toda la función.

   Se puede probar esta función instalándola de la forma habitual. A
   continuacion coloca tu cursor después de la siguiente expresión y presiona
   @k{C-x C-e} @%c(eval-last-sexp).

   ..src > elisp
     (lista-de-longitudes-en-fichero
      "/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/debug.el")
   < src..

   Puede que necesites cambiar la ruta del fichero; la de aqui es para GNU
   Emacs versión 22.1.1. Para cambiar la expresión, cópiala al búfer
   @f{*scratch*} y edítala.

   Ademas, para ver el la longitud completa de la lista, en lugar de una versión
   truncada es posible tener que evaluar lo siguiente:

   ..src > elisp
     (custom-set-variables '(eval-expression-print-length nil))
   < src..

   (Consulta la Seccion @l{#Especificar variables usando @c{defcustom}}. A contituacion
   evalúa la expresión @c{lista-de-longitudes-en-fichero}.)

   La lista de longitudes para @f{debug.el} tarda menos de un segundo en
   producirse y se ve asi en GNU Emacs 22:

   ..srci > elisp
     (83 113 105 144 289 22 30 97 48 89 25 52 52 88 28 29 77 49 43 290 232 587)
   < srci..

   Usando mi vieja máquina, con la versión 19 tambien con @f{debug.el}
   demora siete segundos en producir esto:

   ..srci > elisp
     (75 41 80 62 20 45 44 68 45 12 34 235)
   < srci..

   La versión nueva de @f{debug.el} contiene más defuns que la anterior; y
   mi nueva máquina es mucho más rápida que la vieja.

   Ten en cuenta que el tamaño de la última definición en el fichero es la primera
   de la lista.

** Contar palabras en @c{defuns} en diferentes ficheros

   En la sección anterior, creamos una función que devuelve una lista de las
   longitudes de cada definición en un fichero. Ahora, queremos definir una
   función para devolver una lista maestra de las longitudes de las definiciones
   en una lista de ficheros.

   Trabajar en cada una de las listas de ficheros es un acto repetitivo,
   por lo que podemos usar un bucle @c{while} o recursión.

   El diseño utilizando un bucle @c{while} es rutinario. El argumento que se
   pasa a la función es una lista de ficheros. Como vimos anteriormente (Ver
   Sección @l{#Un bucle @c{while} y una lista}), se puede escribir un bucle
   @c{while} de un modo que el cuerpo del bucle se evalue si tal lista
   contiene elementos, pero que deba salir del bucle si la lista está
   vacía. Para que este diseño funcione, el cuerpo del bucle debe contener una
   expresión que acorte la lista con cada evaluacion del cuerpo, de modo que
   finalmente la lista esté vacía. La técnica usual es asignar el valor de la
   lista al valor del @c{cdr} de la lista cada vez que se evalua el cuerpo.

   La plantilla se ve así:

   ..src > elisp
     (while comprobar-si-la-lista-esta-vacia
       cuerpo…
       asignar-lista-al-cdr-de-la-lista)
   < src..

   Ademas, recordemos que un bucle @c{while} devuelve @c{nil} (el resultado
   de evaluar la prueba-verdadero-o-falso), no el resultado de ninguna evaluación
   dentro de su cuerpo. (Las evaluaciones dentro del cuerpo del bucle se hacen por
   sus efectos secundarios.) Sin embargo, la expresión que establece la lista de
   longitudes es parte del cuerpo––y ese es valor que queremos que devuelva
   la función como un todo. Para hacer esto, rodeamos el bucle @c{while} con
   una expresión @c{let}, y disponemos que el último elemento de la
   expresión @c{let} contiene el valor de lista de longitudes. (Consulta la Seccion
   @l{#Ejemplo con contador incremental}.)

   Estas consideraciones nos llevan directamente a la función en sí:

   ..src > elisp
     ;;; Usar bucle while.
     (defun lista-de-longitudes-de-muchos-ficheros (lista-de-ficheros)
       "Devuelve la lista de longitudes de defuns en LISTA-DE-FICHEROS."
       (let (lista-de-longitudes)

     ;;; prueba-verdadero-o-falso
         (while lista-de-ficheros
           (setq lista-de-longitudes
                 (append
                  lista-de-longitudes

     ;;; Genera una lista de longitudes.
                  (lista-de-longitudes-en-fichero
                   (expand-file-name (car lista-de-ficheros)))))

     ;;; Reducir la lista de ficheros.
           (setq lista-de-ficheros (cdr lista-de-ficheros)))

     ;;; Devuelve el valor final de la lista de longitudes.
         lista-de-longitudes))
   < src..

   @c{expand-file-name} es una función nativa que convierte el nombre de un
   fichero a su nombre de ruta absoluta. La función emplea el nombre
   del directorio en el que se llama la función.

   De este modo, si se llama a @c{expand-file-name} dentro de @c{debug.el} cuando
   Emacs está visitando el directorio @f{/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/}

   ..example >
     debug.el
   < example..

   se convierte en

   ..example >
     /usr/local/share/emacs/22.1.1/lisp/emacs-lisp/debug.el
   < example..

   El único otro nuevo elemento de esta definición de función es la todavía no
   estudiada función @c{append}, que merece una breve sección.

*** La función @c{append}

    La función @c{append} une una lista a otra. De este modo,

    ..src > elisp
      (append '(1 2 3 4) '(5 6 7 8))
    < src..

    produce la lista

    ..src > elisp
      (1 2 3 4 5 6 7 8)
    < src..

    Asi es exactamente cómo queremos unir dos listas de longitudes
    producidas por @c{lista-de-longitudes-en-fichero} entre si. Los resultados
    contrastan con @c{cons},

    ..src > elisp
      (cons '(1 2 3 4) '(5 6 7 8))
    < src..

    que construye una nueva lista en la que el primer argumento de @c{cons}
    se convierte en el primer elemento de la nueva lista:

    ..src > elisp
      ((1 2 3 4) 5 6 7 8)
    < src..

** Contar palabras recursivamente en diferentes ficheros

   Ademas de un bucle @c{while}, podemos trabajar en cada lista de ficheros con
   recursión. Una versión recursiva de @c{lista-de-longitudes-de-muchos-ficheros}
   es corta y simple.

   La función recursiva tiene las partes usuales: la ‘prueba-hazlo-de-nuevo’, la
   ‘expresion-del-siguiente-paso’, y la llamada recursiva. La
   ‘prueba-hazlo-de-nuevo’ determina si la función debe volver a llamarse a si
   misma, lo que hará si la @c{lista-de-ficheros} contiene algun elemento
   restante; la ‘expresion-del-siguiente-paso’ reasigna la @c{lista-de-ficheros}
   con su mismo @c{cdr}, por lo que eventualmente la lista estara vacía; y la
   llamada recursiva se llamara a si misma en la lista mas corta. ¡La función
   completa es mas corta que esta descripción!

   ..src > elisp
     (defun lista-de-longitudes-de-muchos-ficheros-recursiva (lista-de-ficheros)
       "Devuelve la lista de longitudes de cada defun en LISTA-DE-FICHEROS."
       (if lista-de-ficheros                    ; prueba-hazlo-de-nuevo
           (append
            (lista-de-longitudes-en-fichero
             (expand-file-name (car lista-de-ficheros)))
            (lista-de-longitudes-de-muchos-ficheros-recursiva
             (cdr lista-de-ficheros)))))
   < src..

   En una frase, la función devuelve la lista de longitudes para la
   primer @c{lista-de-ficheros} adjunta al resultado de llamarse así misma al
   resto de la @c{lista-de-ficheros}.

   Aquí hay una prueba de @c{lista-de-longitudes-de-muchos-ficheros-recursiva},
   junto con los resultados de ejecutar @c{lista-de-longitudes-en-fichero} en cada
   uno de los ficheros individualmente.

   Instala @c{lista-de-longitudes-de-muchos-ficheros-recursiva} y
   @c{lista-de-longitudes-en-fichero}, y luego evalúa las siguientes
   expresiones. Es posible que necesites cambiar las rutas a los ficheros; las
   que aquí se incluyen funcionan cuando las fuentes de Emacs se encuentran
   en sus lugares habituales. Para cambiar las expresiones, cópialas al búfer
   @f{*scratch*}, edítalas y evalualas.

   (Estos resultados son para ficheros de la versión 22.1.1; los ficheros
   de otras versiones puede producir resultados diferentes.)

   ..srci > elisp
     > (cd "/usr/local/share/emacs/22.1.1/")
     > (lista-de-longitudes-en-fichero "./lisp/macros.el")
     (283 263 480 90)
     > (lista-de-longitudes-en-fichero "./lisp/mail/mailalias.el")
     (38 32 29 95 178 180 321 218 324)
     > (lista-de-longitudes-en-fichero "./lisp/makesum.el")
     (85 181)
     > (lista-de-longitudes-de-muchos-ficheros-recursiva
     ^  '("./lisp/macros.el"
     ^    "./lisp/mail/mailalias.el"
     ^    "./lisp/makesum.el"))
     (283 263 480 90 38 32 29 95 178 180 321 218 324 85 181)
   < srci..

   La función @c{lista-de-longitudes-de-muchos-ficheros-recursiva} produce la salida que
   queremos.

   El siguiente paso es preparar los datos de la lista para visualizarlos en un
   grafico.

** Preparar los datos para visualizarlos en un grafico

   La función @c{lista-de-longitudes-de-muchos-ficheros-recursiva} devuelve una
   lista de números. Cada número registra la longitud de una definición de
   función. Lo que tenemos que hacer ahora es transformar estos datos en una
   lista de números adecuados para generar un grafico. La nueva lista dira
   cuántas definiciones de funcion contienen menos de 10 palabras y símbolos,
   cuantas entre 10 y 19, cuántas entre 20 y 29, y así sucesivamente.

   En resumen, necesitamos revisar la lista de longitudes producida por la
   función @c{lista-de-longitudes-de-muchos-ficheros-recursiva} y contar el
   número de definiciones dentro de cada rango, y producir una lista de esos
   números.

   Basado en lo que hemos hecho antes, podemos preveer que no sera demaciado difícil
   escribir una función que redusca la lista de longitudes con ‘@c{cdr}s’, mire
   cada elemento, determine en que rango de longitud esta, e incremente un
   contador para ese rango.

   Sin embargo, antes de empezar a escribir tal función, debemos
   considerar las ventajas de primero ordenar la lista de longitudes,
   de modo que los números se ordenen del más pequeño al más grande. En primer lugar,
   la ordenacion facilitara el conteo de los números en el mismo rango, ya que dos
   números adyacentes estaran en el mismo rango de longitud o en rangos
   adyacentes. Segundo, inspeccionando una lista ordenada, podemos descubrir
   el número mas alto y el mas bajo, y asi determinar el rango de longitud mas
   grande y mas pequeño que necesitaremos.

*** Ordenando listas

    Emacs contiene una función para ordenar listas, llamada (como se
    podría adivinar) @c{sort}. La función @c{sort} toma dos argumentos, la
    lista a ordenar, y un predicado que determina si el primero de dos
    elementos de la lista es “menor” que el segundo.

    Como vimos anteriormente (Ver Sección @l{#Usando el tipo incorrecto de objeto
    como argumento}), un predicado es una función que determina si alguna
    propiedad es verdadera o falsa. La función @c{sort} reordenará una lista de
    acuerdo a cualquier propiedad que use el predicado; esto significa que
    @c{sort} puede usarse para ordenar listas no numéricas por un criterio no
    numérico––puede, por ejemplo, ordenar la lista alfabeticamente.

    La función @c{<} se utiliza para ordena una lista numérica. Por ejemplo,

    ..src > elisp
      (sort '(4 8 21 17 33 7 21 7) '<)
    < src..

    produce esto:

    ..src > elisp
      (4 7 7 8 17 21 21 33)
    < src..

    (Ten en cuenta que en este ejemplo, ambos argumentos se citan para que no
    se evaluen los símbolos antes de pasarlos a @c{sort} como argumentos.)

    Ordenar la lista devuelta por la función
    @c{lista-de-longitudes-de-muchos-ficheros-recursiva} es sencillo; utilizando
    la función @c{<}:

    ..src > elisp
      (sort
       (lista-de-longitudes-de-muchos-ficheros-recursiva
        '("./lisp/macros.el"
          "./lisp/mailalias.el"
          "./lisp/makesum.el"))
       '<)
    < src..

    que produce:

    ..src > elisp
      (29 32 38 85 90 95 178 180 181 218 263 283 321 324 480)
    < src..

    (Nota que en este ejemplo, el primer argumento para @c{sort} no se cita,
    ya que la expresión debe ser evaluada para producir la lista que se
    pasada a @c{sort}.)

*** Creando una lista de ficheros

    La función @c{lista-de-longitudes-de-muchos-ficheros-recursiva} requiere una
    lista de ficheros como argumento. Para nuestros ejemplos de prueba, hemos
    construido una lista de este tipo a mano; pero el directorio fuente de Emacs
    Lisp es demasiado grande para que podamos hacerlo. En su lugar, escribiremos
    una función para hacer el trabajo por nosotros. En esta función, usaremos
    tanto un bucle @c{while} como una llamada recursiva.

    En las viejas versiones de GNU Emacs no hacia falta escribir esta función,
    ya que todos los ficheros @'{.el} estaban colocados en un directorio. En su
    lugar, pudimos usar la función @c{directory-files}, que lista los nombres de
    los ficheros que coinciden con un patron especifico dentro de un solo
    directorio.

    Sin embargo, las versiones recientes de Emacs colocan los ficheros de Emacs
    Lisp en subdirectorios del directorio @f{lisp} de nivel superior. Esta
    reorganizacion facilita la navegación. Por ejemplo, todos los ficheros
    relacionados con el correo están en el subdirectorio @f{mail}. Pero al mismo
    tiempo, esta estructura nos obliga a crear una funcion de listado de
    ficheros que descienda dentro de los subdirectorios.

    Podemos crear esta función, llamada @c{ficheros-en-el-siguiente-directorio},
    usando funciones familiares como @c{car}, @c{nthcdr}, y @c{substring} en
    conjunción con una función existente llamada @c{directory-files-and-attributes}.
    Esta última función no solo listas todos los ficheros en un directorio,
    incluyendo los nombres de los subdirectorios, también sus atributos.

    Repitamos nuestro objetivo: crear una función que nos permita alimentar a
    @c{lista-de-longitudes-de-muchos-ficheros-recursiva} con nombres de fichero
    en una lista parecida a esta (pero con más elementos):

    ..src > elisp
      ("./lisp/macros.el"
       "./lisp/mail/rmail.el"
       "./lisp/makesum.el")
    < src..

    La función @c{directory-files-and-attributes} devuelve una lista de
    listas. Cada una de las listas de la lista principal consiste de 13
    elementos. El primer elemento es una cadena que contiene el nombre del
    fichero––que, en GNU/Linux, puede ser un ‘fichero de directorio’, es decir,
    un fichero con los atributos especiales de un directorio. El segundo
    elemento de la lista es @c{t} para un directorio, una cadena para el
    enlace simbólico (la cadena es el nombre al que enlaza), o @c{nil}.

    Por ejemplo, el primer fichero @'{.el} en el directorio @f{abbrev.el} es
    @f(abbrev.el). Su nombre es @f{/usr/local/share/emacs/22.1.1/lisp/abbrev.el}
    y no es un directorio o un enlace simbólico.

    Asi es cómo @c{directory-files-and-attributes} lista este fichero y sus
    atributos:

    ..src > elisp
      ("abbrev.el"
       nil
       1
       1000
       100
       (20615 27034 579989 697000)
       (17905 55681 0 0)
       (20615 26327 734791 805000)
       13188
       "-rw-r--r--"
       nil
       2971624
       773)
    < src..

    Por otro lado, @f{mail/} es un directorio dentro del directorio @f{lisp/}. El
    inicio del listado se ve asi:

    ..src > elisp
      ("mail"
       t
       …
       )
    < src..

    (Para conocer los diferentes atributos, mira en la documentación de
    @c{file-attributes}. Ten en mente que la función @c{file-attributes} no
    lista el nombre del fichero, por lo que el primer elemento es el segundo
    elemento de @c{directory-files-and-attributes}.)

    Quisieramos que nuestra nueva funcion, @c{ficheros-bajo-el-dirirectorio},
    listara los ficheros @'{.el} en el directorio que le pedimos inspeccionar,
    y en cualquier directorio debajo de ese directorio.

    Esto nos da una pista de como construir @c{ficheros-bajo-el-dirirectorio}:
    dentro de un directorio, la función deberia añadir los ficheros @'{.el} a
    una lista; y si, dentro de un directorio, la función se encuentra con un
    subdirectorio, ir dentro de este subdirectorio y repetir sus acciones.

    Sin embargo, debemos tener en cuenta que cada directorio contiene un nombre
    que hace referencia a sí mismo, llamado @f{.}, (“punto”) y un nombre que
    hace referencia a su directorio padre, llamado @f{..} (“doble punto”). (En
    @f{/}, el directorio raíz, @f{..} se refiere así mismo, ya que @f{/} no
    tiene padre.) Claramente, no queremos que nuestra función
    @c{ficheros-bajo-el-dirirectorio} ingrese a estos directorios, puesto que nos
    llevaran directamente o indirectamente, al directorio actual.

    Por consiguiente, nuestra función @c{ficheros-bajo-el-dirirectorio} debe realizar
    varias tareas:

    - Probar si se está mirando un nombre de fichero que finaliza en @'{.el} y
      si es así, añadir su nombre a una lista.

    - Probar si está mirando en un nombre de fichero que es el
      nombre de un directorio; y si es así,

      - Probar si está mirando en @f{.} o @f{..}; y si es así omitirlo.

      - Si no, ir dentro de ese directorio y repetir el proceso.


    Escribamos una definición de función para realizar estas tareas. Usaremos un
    bucle @c{while} para movernos de un nombre de fichero a otro con un
    directorio comprobando lo que hay que hacer; y usaremos una llamada
    recursiva para repetir las acciones en cada subdirectorio. El patrón
    recursivo es ‘accumulate’ (Consulta la Sección @l{#Patrón recursivo:
    @e{accumulate}}) usando @c{append} como combinador.

    Aquí está la función:

    ..src > elisp
      (defun ficheros-bajo-el-dirirectorio (directorio)
        "Lista los ficheros .el en DIRECTORIO y en sus subdirectorios."
        ;; Aunque la función se utilizara no interactivamente,
        ;; será mas fácil de probar si la hacemos interactiva.
        ;; El directorio tendrá un nombre como
        ;;  "/usr/local/share/emacs/22.1.1/lisp/"
        (interactive "DNombre del Directorio: ")
        (let (lista-de-ficheros-el
              (lista-del-directorio-actual
               (directory-files-and-attributes directorio t)))
          ;; mientras estamos en el directorio actual
          (while lista-del-directorio-actual
            (cond
             ;; realiza una prueba para ver si el nombre del fichero termina
             ;; en ‘.el’ y si es así, añade su nombre a una lista.
             ((equal ".el" (substring (car (car lista-del-directorio-actual)) -3))
              (setq lista-de-ficheros-el
                    (cons (car (car lista-del-directorio-actual)) lista-de-ficheros-el)))
             ;; prueba si el nombre del fichero es un directorio
             ((eq t (car (cdr (car lista-del-directorio-actual))))
              ;; decide si ignorarlo o hacer recursión
              (if
                  (equal "."
                         (substring (car (car lista-del-directorio-actual)) -1))
                  ;; entonces no hacer nada puesto que el nombre del fichero es
                  ;; el directorio actual o el padre, "." o ".."
                  ()
                ;; de otra forma, desciende dentro del directorio y repite el proceso
                (setq lista-de-ficheros-el
                      (append
                       (ficheros-bajo-el-dirirectorio
                        (car (car lista-del-directorio-actual)))
                       lista-de-ficheros-el)))))
            ;; moverse al siguiente fichero en la lista; esto también acorta
            ;; la lista para que el bucle while eventualmente llegue a su fin
            (setq lista-del-directorio-actual (cdr lista-del-directorio-actual)))
          ;; devuelve los ficheros
          lista-de-ficheros-el))
    < src..

    La funcion @c{ficheros-bajo-el-dirirectorio} toma un argumento, el nombre de
    un directorio.

    Por eso, en mi sistema,

    ..src > elisp
      (length
       (ficheros-bajo-el-dirirectorio "/usr/local/share/emacs/22.1.1/lisp/"))
    < src..

    me dice que en y debajo de mi directorio de codigo fuente Lisp hay 1031
    ficheros @'f{.el}

    @c{ficheros-bajo-el-dirirectorio} devuelve una lista en orden alfabético
    inverso. Una expresión para ordenar la lista en orden alfabetico tiene el
    siguiente aspecto:

    ..src > elisp
      (sort
       (ficheros-bajo-el-dirirectorio "/usr/local/share/emacs/22.1.1/lisp/")
       'string-lessp)
    < src..

*** Contando definiciones de función

    Nuestro objetivo inmediato es generar una lista que nos diga cuantas
    definiciones de funcion contienen menos de 10 palabras y símbolos, cuantas
    contienen entre 10 y 19 palabras y símbolos, cuantas entre 20 y 29, y así
    sucesivamente.

    Con una lista ordenada de números, esto es fácil: se cuentan cuantos
    elementos de la lista son más pequeños de 10, luego, despues de haber pasado
    los numeros que se acaban de contar, se cuenta cuantos son más pequeños de
    20, despues de haber pasado los numeros que se acaban de contar, los que son
    más pequeños de 30, y así sucesivamente. Cada uno de los números, 10, 20,
    30, 40, y similares, es uno más grande que la parte superior de ese
    rango. Podemos llamar a esta lista de estos numeros, @c{cima-de-rangos}.

    Si quisieramos, podriamos generar esta lista automáticamente, pero es más
    sencillo escribir una lista manualmente. Aquí está:

    ..src > elisp
      (defvar cima-de-rangos
       '(10  20  30  40  50
         60  70  80  90 100
        110 120 130 140 150
        160 170 180 190 200
        210 220 230 240 250
        260 270 280 290 300)
       "Listar especificando rangos para ‘definiciones-por-rango’.")
    < src..

    Para cambiar los rangos, editamos esta lista.

    A continuacion, necesitamos escribir la función que crea la lista del número
    de definiciones dentro de cada rango. Evidentemente, esta función debe tomar las
    listas @c{longitudes-ordenadas} y @c{cima-de-rangos} como argumentos.

    La función @c{definiciones-por-rango} debe hacer dos cosas una y otra vez:
    debe contar el número de definiciones con un rango específicado por el valor
    superior actual del rango; y debe pasar al siguiente valor superior en la
    lista @c{cima-de-rangos} después de contar el número de definiciones en el
    rango actual. Dado que cada una de estas acciones es repetitiva, se pueden
    utilizar bucles @c{while} para el trabajo. Un bucle cuenta el número de
    definiciones en el rango definido por el valor superior actual, y el otro
    bucle a su vez selecciona cada uno de los valores superiores del rango.

    Se cuentan varias entradas de la lista de @c{longitudes-ordenadas} para cada
    rango; esto significa que el bucle para la lista de @c{longitudes-ordenadas}
    estara dentro del bucle para la lista de @c{cima-de-rangos}, como un pequeño
    engrane dentro de un gran mecanismo.

    El bucle interno cuenta el número de definiciones dentro del rango. Es un
    simple bucle de conteo del tipo que hemos visto antes. (Ver la Seccion @l{#Un
    bucle con un contador incremental}). La prueba verdadero-o-falso del bucle
    comprueba si el valor de la lista @c{longitudes-ordenadas} es menor que el
    valor actual de la cima del rango. Si es así, la función incrementa el
    contador y prueba el siguiente valor de la lista @c{longitudes-ordenadas}.

    El bucle interno se ve asi:

    ..src > elisp
      (while elemento-de-longitud-menor-que-el-de-la-cima-de-rango
        (setq numero-dentro-del-rango (1+ numero-dentro-del-rango))
        (setq longitudes-ordenadas (cdr longitudes-ordenadas)))
    < src..

    El bucle exterior debe empezar con el valor más bajo de la lista
    @c{cima-de-rangos} y, a continuacion, ajustarse a cada uno de los valores
    superiores sucesivos. Esto puede ser hecho con un bucle como
    este:

    ..src > elisp
      (while cima-de-rangos
        cuerpo-del-bucle…
        (setq cima-de-rangos (cdr cima-de-rangos)))
    < src..

    Puestos juntos, los dos bucles se ven asi:

    ..src > elisp
      (while cima-de-rangos

        ;; Cuenta el número de elementos dentro del rango actual.
        (while elemento-de-longitud-menor-que-el-de-la-cima-de-rango
          (setq numero-dentro-del-rango (1+ numero-dentro-del-rango))
          (setq longitudes-ordenadas (cdr longitudes-ordenadas)))

        ;; Mover al siguiente rango.
        (setq cima-de-rangos (cdr cima-de-rangos)))
    < src..

    Además, en cada iteracion del bucle exterior, Emacs debe registrar el número de
    definiciones dentro de ese rango (el valor de @c{numero-dentro-del-rango}) en una
    lista. Podemos usar @c{cons} para este propósito. (Consulta la Seccion
    @l{#@c{cons}}.)

    La función @c{cons} trabaja bien, excepto que la lista que construye
    contendrá el número de definiciones para el rango mas alto y el número de
    definiciones para el rango más bajo al final. Esto se debe a que @c{cons}
    adjunta nuevos elementos de la lista al principio de la lista, y ya que los
    dos bucles hacen cálculos a través de la lista de longitudes iniciando desde el
    extremo inferior, la @c{lista-de-definiciones-por-rango}
    terminara con el numero mayor al pricipio. Pero querremos imprimir nuestro
    grafo con los valores pequeños primero y los más grandes después. La
    solución es invertir el orden de la @c{lista-de-definiciones-por-rango}.
    Podemos hacer esto usando la función @c{nreverse}, que invierte el orden de
    una lista.

    Por ejemplo,

    ..src > elisp
      (nreverse '(1 2 3 4))
    < src..

    produce:

    ..src > elisp
      (4 3 2 1)
    < src..

    Advertir que la función @c{nreverse} es “destructiva”––es decir, cambia la
    lista a la que se aplica; esto contrasta con las funciones @c{car} y
    @c{cdr}, que no son destructivas. En este caso, no queremos la
    @c{lista-de-definiciones-por-rango} original, asi que no importa que sea
    destruida. (La función @c{reverse} proporciona un copia inversa de una lista,
    dejando la lista original tal cual.)

    En conjunto, la funcion @c{definiciones-por-rango} luce asi:

    ..src > elisp
      (defun definiciones-por-rango (longitudes-ordenadas cima-de-rangos)
        "LONGITUDES-ORDENADAS de defuns en cada CIMA-DE-RANGOS."
        (let ((cima-de-rango (car cima-de-rangos))
              (numero-dentro-del-rango 0)
              lista-de-definiciones-por-rango)

          ;; Bucle Externo.
          (while cima-de-rangos

            ;; Bucle Interno.
            (while (and
                    ;; Necesita el número para la prueba numérica.
                    (car longitudes-ordenadas)
                    (< (car longitudes-ordenadas) cima-de-rango))

              ;; Cuenta el número de definiciones dentro del rango actual.
              (setq numero-dentro-del-rango (1+ numero-dentro-del-rango))
              (setq longitudes-ordenadas (cdr longitudes-ordenadas)))

            ;; Sale del bucle interno pero permanece dentro del bucle externo.

            (setq lista-de-definiciones-por-rango
                  (cons numero-dentro-del-rango lista-de-definiciones-por-rango))
            (setq numero-dentro-del-rango 0)      ; Restablece el conteo a cero.

            ;; Mover al siguiente rango.
            (setq cima-de-rangos (cdr cima-de-rangos))
            ;; Designa el siguiente valor superior del rango.
            (setq cima-de-rango (car cima-de-rangos)))
          ;; Sale del bucle externo y cuenta el número de defuns mayor que
          ;; el valor mas alto de cima-de-rango.
          (setq lista-de-definiciones-por-rango
                (cons
                 (length longitudes-ordenadas)
                 lista-de-definiciones-por-rango))

          ;; Devuelve una lista del número de definiciones dentro de cada rango,
          ;;   del menor al mayor.
          (nreverse lista-de-definiciones-por-rango)))
    < src..

    La función es sencilla, excepto por una caracteristica sutil. La prueba
    verdadero-o-falso del bucle interno es asi:

    ..src > elisp
      (and (car longitudes-ordenadas)
           (< (car longitudes-ordenadas) cima-de-rango))
    < src..

    en lugar de asi:

    ..src > elisp
      (< (car longitudes-ordenadas) cima-de-rango)
    < src..

    El propósito de la prueba es determinar si el primer elemento de la lista
    de @c{longitudes-ordenadas} es inferior al valor de la parte superior del rango.

    La versión simple de la prueba funciona bien a menos que la lista
    @c{longitudes-ordenadas} tenga un valor @c{nil}. En este caso, la expresión
    @c{(car longitudes-ordenadas)} devuelve @c{nil}. La función @c{<} no puede
    compara un número con @c{nil}, que es una lista vacía, por lo que Emacs indica un
    error e impide que la función siga ejecutandose.

    La lista de @c{longitudes-ordenadas} siempre se convierte en @c{nil} cuando el
    contador llega al fin de la lista. Esto significa que cualquier intento
    de usar la función @c{definiciones-por-rango} con la versión simple de la prueba
    fallará.

    Resolvemos el problema usando la expresion @c{(car longitudes-ordenadas)}
    junto con la expresión @c{and}. La expresión @c{(car longitudes-ordenadas)}
    devuelve un valor no @c{nil} siempre y cuando la lista contenga al menos un
    número, pero devuelve @c{nil} si la lista está vacía. La expresión @c{and}
    primero evalúa @c{(car longitudes-ordenadas)}, y si es @c{nil}, devuelve
    falso @e{sin} evaluar la expresión @c{<} y devuelve este valor como el valor
    de la expresión @c{and}.

    De esta manera, evitamos un error.  (Para mas información sobre @c{and},
    consulta la Seccion @l{#La función @c{kill-new}}

    He aqui una breve prueba de la función @c{definiciones-por-rango}. Primero,
    evalúa la expresión que enlaza la lista (ordenada) @c{cima-de-rangos} a
    la lista de valores, luego evalúa la expresión que enlaza la lista
    @c{longitudes-ordenadas}, y despues evalúa la función @c{definiciones-por-rango}.

    ..src > elisp
      ;; (La lista ordenada que usaremos después.)
      (setq cima-de-rangos
       '(110 120 130 140 150
         160 170 180 190 200))

      (setq longitudes-ordenadas
            '(85 86 110 116 122 129 154 176 179 200 265 300 300))

      (definiciones-por-rango longitudes-ordenadas cima-de-rangos)
    < src..

    Esta es la lista que devuelve:

    ..src > elisp
      (2 2 2 0 0 1 0 2 0 0 4)
    < src..

    De hecho, hay dos elementos de la lista @c{longitudes-ordenadas} menores a 110,
    dos elementos entre 110 y 119, dos elementos entre 120 y 129, etcetera. Hay
    cuatro elementos con un valor de 200 o superior.

* Preparar un grafico

  Nuestro objetivo es construir un grafo que muestre el numero de definiciones
  de función de varios tamaños en el codigo fuente de Emacs lisp.

  Como cuestion práctica, si estuvieras creando un grafico, probablemente
  usarías un programa como @${gnuplot} para hacer el trabajo. (@${gnuplot} está
  bien integrado dentro de GNU Emacs.) En este caso, sin embargo, creamos uno
  desde cero, y en el proceso volveremos a familiarizarnos con algo de lo
  que aprendimos antes y aprenderemos más.

  En este capítulo, primero escribiremos una simple funcion de impresion de
  graficos. Esta primera definición será un @:{prototipo}, una función escrita
  rápidamente que nos permita reconocer este territorio desconocido en la
  creacion de graficos. Descubriremos dragones, o descubriremos que son
  mitos. Después de explorar el terreno, nos sentiremos más seguros y
  mejoraremos la función para etiquetar las coordenadas automáticamente.

  Dado que Emacs está diseñado para ser flexible y funcionar con todo tipo de
  terminales, incluyendo los terminales de solo caracteres, el grafico debera
  realizarse a partir de uno de los simbolos de ‘maquina de escribir’. Un asterisco
  servira; a medida que mejoremos la función de impresión del grafico, podremos
  hacer que el simbolo a usar sea una elección del usuario.

  Podemos llamar a esta función @c{imprimir-cuerpo-grafico}; tomará como unico
  argumento una @c{lista-de-numeros}. En esta etapa, no etiquetaremos el grafico,
  sino que solo imprimiremos su cuerpo.

  La función @c{imprimir-cuerpo-grafico} inserta una columna vertical de asteriscos
  para cada elemento en la @c{lista-de-numeros}. La altura de cada línea
  está determinada por el valor de ese elemento de la @c{lista-de-numeros}.

  Insertar columnas es un acto repetitivo; esto significa que esta función
  puede escribirse con un bucle @c{while} o recursivamente.

  Nuestro primer reto es descubrir como imprimir una columna de
  asteriscos. Normalmente, en Emacs, se imprimen caracteres dentro de una
  pantalla horizontalmente, escribiendo línea a línea. Tenemos dos rutas
  a seguir: escribir nuestra propia función de insercion-de-columnas o descubrir
  si ya existe una en Emacs.

  Para ver si hay una en Emacs, podemos usar el comando @k{M-x apropos}. Este
  comando es como el comando @k{C-h a} @%c(command-apropos), excepto que este
  último solo encuentra aquellas funciones que son comandos. El comando @k{M-x
  apropos} lista todos los símbolos que coinciden con una expresión regular,
  incluyendo funciones que no son interactivas.

  Lo que queremos buscar es algún comando que imprima o inserte columnas. Muy
  probablemente, el nombre de la función contendrá la palabra ‘print’ o la
  palabra ‘insert’ o la palabra ‘column’. Por esta razón, podemos simplemente
  escribir @k{M-x apropos RET print\|insert\|column RET} y ver el resultado. En
  mi sistema, este comando demoro bastante tiempo, y luego produjo una
  lista de 79 funciones y variables. Ahora no demora mucho y produce una
  lista de 211 funciones y variables. Explorando la lista, la única función que
  parece puede hacer el trabajo es @c{insert-rectangle}.

  De hecho, esta es la función que queremos; su documentación dice:

  ..example >
    insert-rectangle:
    Insertar texto de RECTANGLE con la esquina superior izquierda en el punto
    La primera línea de RECTANGLE se inserta en el punto
    la segunda línea se inserta en un punto verticalmente debajo del punto, etc
    RECTANGLE debe ser una lista de cadenas.
    Después de este comando, la marca está en la esquina izquierda
    superior y el punto en la esquina inferior derecha.
  < example..

  Podemos ejecutar una prueba rápida, para asegurarnos de que hace lo que esperamos.

  Este es el resultado de colocar el cursor después de la expresión
  @c{insert-rectangle} y presionar @k{C-u C-x C-e} @%c(eval-last-sexp). La
  función inserta las cadenas @c{"primero"}, @c{"segundo"}, y @c{"tercero"}
  debajo del punto. También la función devuelve @c{nil}.

  ..example >
    (insert-rectangle '("primero" "segundo" "tercero"))primero
                                                       segundo
                                                       terceronil
  < example..

  Por supuesto, no insertaremos el texto de la expresión @c{insert-rectangle} en
  el búfer en el que estamos haciendo el grafico, sino qque llamaremos a la
  función desde nuestro programa. Sin embargo, tendremos que asegurarnos de que
  el punto está en el búfer en el lugar donde la función
  @c{insert-rectangle} insertará la columna de cadenas.

  Si estás leyendo esto en Emacs, puedes ver como funciona cambiando a otro
  búfer, como el búfer @f{*scratch*}, colocar el punto a algún lugar del búfer,
  presionar @k{M-:}, despues escribir la expresión @c{insert-rectangle} dentro
  del minibúfer en la consola, y presionar @k{RET}. Esto hace que Emacs evalúe
  la expresión en el minibúfer, pero utilice como el valor del punto la posición
  del punto en el búfer @f{*scratch*}. (@k{M-:} es el atajo para
  @c{eval-expression}. Tampoco aparece @c{nil} en el búfer @f{*scratch*}, ya que
  la expresión se evalúa en el minibúfer.)

  Cuando hacemos esto, encontraremos que el punto termina al final de la
  última línea insertada––es decir, esta función mueve el punto como un
  efecto secundario. Si repitieramos el comando, con el punto en esta
  posición, la siguiente inserción estaria debajo y a la derecha de la
  inserción anterior. ¡No queremos esto!. Si vamos a crear un
  gráfico de barras, las columnas deben estar una al lado de la otra.

  Así descubrimos que cada ciclo de insercion de columnas del bucle @c{while}
  debe reposicionar el punto al lugar que queremos, y ese lugar estará en la
  parte superior, no en la inferior de la columna. Ademas, recordamos que cuando
  imprimimos un grafico, no se espera que todas las columnas tengan la misma
  altura. Esto significa que la parte superior de cada columna puede estar a una
  altura diferente de la anterior. No podemos simplemente reposicionar el punto
  en la misma línea cada vez, sino movernos hacia la derecha––o tal vez podamos…

  Estamos planeando crear las columnas del grafico de barras con asteriscos. El
  número de asteriscos en la columna es el número específicado por el elemento
  actual de la @c{lista-de-numeros}. Necesitamos construir una lista de asteriscos
  de la longitud correcta para cada llamada a @c{insert-rectangle}. Si esta lista
  consiste únicamente del número requerido de asteriscos, entonces tendremos
  la posición de punto el número correcto de líneas sobre la base del gráfico
  para imprimirse correctamente. Esto podría ser difícil.

  Alternativamente, si podemos encotrar alguna manear de pasar a
  @c{insert-rectangle} una lista de la misma longitud cada vez, entonces podemos
  posicionar el punto en la misma línea cada vez, pero moverlo una
  columna a la derecha para cada nueva columna. Si hacemos esto, sin embargo,
  algunas de las entradas en la lista pasaba a @c{insert-rectangle} deben ser
  espacios en blanco en vez de asteriscos. Por ejemplo, si la altura máxima del
  grafico es 5, pero la altura de la columna es 3, entonces @c{insert-rectangle}
  requiere un argumento como este:

  ..src > elisp
    (" " " " "*" "*" "*")
  < src..

  Esta última propuesta no es tan difícil, siempre y cuando podamos determinar
  la altura de la columna. Hay dos maneras de especificar la altura de la
  columna: podemos indicar arbitrariamente cual sera, lo que funcionaría bien
  para gráficos de esa altura; o podemos buscar a través de la lista de números
  y usar la altura máxima de la lista como la altura máxima del grafico. Si la
  segunda operación fuera difícil, entonces el procedimiento anterior seria mas fácil,
  pero hay una función nativa en Emacs para determinar el máximo de sus
  argumentos. Podemos usar esta función. La función se llama @c{max} y
  devuelve el mayor de todos sus argumentos, que deben ser números. Asi, por
  ejemplo,

  ..src > elisp
    (max  3 4 6 5 7 3)
  < src..

  devuelve 7. (Una función correspondiente llamada @c{min} devuelve el más
  pequeño de todos sus argumentos.)

  Sin embargo, no podemos simplemente llamar a @c{max} sobre la @c{lista-de-numeros};
  la función @c{max} espera números como su argumento, no una lista de
  números. De este modo, la siguiente expresión,

  ..src > elisp
    (max '(3 4 6 5 7 3))
  < src..

  produce el siguiente mensaje error:

  ..example >
    Tipo incorrecto de argumento: number-or-marker-p, (3 4 6 5 7 3)
  < example..

  Necesitamos una función que pase una lista de argumentos a una
  función. Esa función es @c{apply}. Esta función ‘aplica’ su primer
  argumento (una función) a los argumentos restantes, el último puede
  ser una lista.

  Por ejemplo,

  ..src > elisp
    (apply 'max 3 4 7 3 '(4 8 5))
  < src..

  devuelve 8

  (Por cierto, no cómo aprenderias sobre esta función sin un libro como este. Es
  posible descubrir otras funciones, como @c{search-forward} o
  @c{insert-rectangle}, adivinando una parte de sus nombres y luego usando
  @c{apropos}. Aunque su base metafórica es clara––‘apply’ @%i(aplicar) su primer
  argumento al resto––dudo que a un novato se le ocurra esa palabra en
  particular usando @c{apropos} u otra ayuda. Por supuesto, podría estar
  equivocado; después de todo, la función fué nombrada por primera vez por
  alguien que la tuvo que inventar.

  El segundo y siguientes argumentos de @c{apply} son opcionales, por lo que
  podemos usar @c{apply} para llamar a una función y pasarle los elementos de una
  lista, de la siguiente manera, que también devuelve 8:

  ..src > elisp
    (apply 'max '(4 8 5))
  < src..

  Este ultima forma es la que usaremos para @c{apply}. La función
  @c{lista-de-longitudes-de-muchos-ficheros-recursiva} devuelve una lista de
  números a la que podemos aplicar @c{max} (tambien podriamos aplicar @c(max) a
  la lista de números ordenados; no importa si la lista está ordenada o no).

  Por lo tanto, la operación para encontrar la altura máxima del grafico es esta:

  ..src > elisp
    (setq altura-maxima-del-grafico (apply 'max lista-de-numeros))
  < src..

  Ahora podemos volver a la pregunta de como crear una lista de cadenas para
  una columna del grafico. Indicando la máxima altura del grafico y el número de
  asteriscos que aparecerían en la columna, la función devolverá una lista de
  cadenas para el comando @c{insert-rectangle}.

  Cada columna se compone de asteriscos o espacios en blanco. Puesto que pasamos
  a la función la altura de la columna y el número de asteriscos en ella, el
  número de espacios en blanco se puede encontrar restando los asteriscos de la
  altura. Dado el número de espacios en blanco y el número de asteriscos,
  podemos usar dos bucles @c{while} para construir la lista:

  ..src > elisp
    ;;; Primera versión.
    (defun columna-del-grafico (altura-maxima-del-grafico altura-real)
      "Devuelve la lista de cadenas que es una columna de un grafico."
      (let ((lista-de-insercion nil)
            (numero-de-espacios
             (- altura-maxima-del-grafico altura-real)))

        ;; Rellenar los asteriscos.
        (while (> altura-real 0)
          (setq lista-de-insercion (cons "*" lista-de-insercion))
          (setq altura-real (1- altura-real)))

        ;; Rellena los espacios.
        (while (> numero-de-espacios 0)
          (setq lista-de-insercion (cons " " lista-de-insercion))
          (setq numero-de-espacios
                (1- numero-de-espacios)))

        ;; Devuelve la lista completa.
        lista-de-insercion))
  < src..

  Si instalas esta función y luego evaluas la siguiente expresión, veras que
  devuelve la lista como se desea:

  ..src > elisp
    (columna-del-grafico 5 3)
  < src..

  devuelve

  ..src > elisp
    (" " " " "*" "*" "*")
  < src..

  Como está escrito, @c{columna-del-grafico} contiene un defecto importante:
  los símbolos usados para el espacio y las entradas marcadas en la columna
  estan ‘incrustados en el codigo’ como un espacio y un asterisco. Esto está
  bien para un prototipo, pero tu, u otro usuario, pueden querer usar otros
  símbolos. Por ejemplo, al probar la función del grafico, podrias querer usar
  un punto en vez del espacio, para asegurar que el punto se está colocando
  apropiadamente cada vez que se llama a la función @c{insert-rectangle}; o tal
  vez quieras sustituir un signo de asterisco por @'{+}. Incluso es posible
  querer crear un grafico de columna que tenga mas de una columna de
  visualizacion. El programa debería ser más flexible. La forma de hacerlo
  es reemplazar el espacio en blanco y el asterisco con dos variables que
  podemos llamar @c{simbolo-en-blanco} y @c{simbolo-grafico} y definir esa variables
  por separado.

  Ademas, la documentación no está bien escrita. Estas consideraciones nos llevan
  a la segunda versión de la función:

  ..src > elisp
    (defvar simbolo-grafico "*"
      "Cadena utilizada como símbolo en el grafico, normalmente un asterisco.")

    (defvar simbolo-en-blanco " "
      "Cadena utilizada como un espacio en blanco en el grafico, normalmente un espacio en blanco.
    simbolo-en-blanco debe tener el mismo número de columnas de ancho que simbolo-grafico.")
  < src..

  (Para una explicación de @c{defvar}, consulta la seccion @l{#Inicializando una
  variable con @c{defvar}}.)

  ..src > elisp
    ;;; Segunda versión.
    (defun columna-del-grafico (altura-maxima-del-grafico altura-real)
      "Devuelve cadenas con la ALTURA-MAXIMA-DEL-GRAFICO; ALTURA-REAL son símbolos graficos.

    Los simbolo-graficos son entradas contiguas al final de la lista.
    La lista se insertara como una columna de un grafico.
    Las cadenas contienen tanto simbolos en blanco como simbolos graficos."

      (let ((lista-de-insercion nil)
            (numero-de-espacios
             (- altura-maxima-del-grafico altura-real)))

        ;; Rellena con simbolo-grafico.
        (while (> altura-real 0)
          (setq lista-de-insercion (cons simbolo-grafico lista-de-insercion))
          (setq altura-real (1- altura-real)))

        ;; Rellena con simbolo-en-blanco.
        (while (> numero-de-espacios 0)
          (setq lista-de-insercion (cons simbolo-en-blanco lista-de-insercion))
          (setq numero-de-espacios
                (1- numero-de-espacios)))

        ;; Devuelve la lista completa.
        lista-de-insercion))
  < src..

  Si quisieramos, podríamos reescribir @c{columna-del-grafico} una tercera vez
  para proporcionar la opcion de crear un gráfico de líneas, como gráfico de
  barras. Esto no sería dificil de hacer. Una manera de pensar en un grafico de
  líneas es que no es más que un grafico de barras en el que la parte de cada
  barra que está debajo la parte superior esta en blanco. Para construir una
  columna para gráfico de líneas, la función primero construyen una lista de
  espacios en blanco que es más pequeña que el valor en uno, luego usa
  @c{cons} para adjuntar un símbolo gráfico a la lista; despues usa @c{cons} de
  nuevo para adjuntar el ‘alto de espacios en blanco’ a la lista.

  Es fácil ver como escribir una función de este tipo, pero puesto que no la
  necesitamos, no se hará. Pero el trabajo podría hacerse, y si se hiciera, se
  haría con @c{columna-del-grafico}. Y lo que es más importante, señalar que
  pocos cambios tendrían que realizarce en otro lugar. La mejora,
  si alguna vez la hacemos, es simple.

  Ahora, finalmente, llegamos a nuestra primer función real de impresion de
  graficos. Esta imprime el cuerpo de un grafico, no las etiquetas para los ejes
  horizontal y vertical, así que podemos nombrarla como @c{imprimir-cuerpo-grafico}.

** La función @c{imprimir-cuerpo-grafico}

   Después de nuestra preparación en la sección anterior, la función
   @c{imprimir-cuerpo-grafico} es sencilla. La función imprimirá columna tras
   columna de asteriscos y espacios en blanco, usando los elementos de la
   lista de números para especificar el número de asteriscos en cada columna.
   Este es un acto repetitivo, lo que significa que podemos utilizar un bucle
   @c{while} decreciente o una función recursiva para el trabajo. En esta
   sección, escribiremos la definición usando un bucle @c{while}.

   La función @c{columna-del-grafico} requiere como argumento la altura del
   grafico, por lo que debemos determinar y registrarla como una variable local.

   Esto nos lleva a la siguiente plantilla para la version con el bucle
   @c{while} de esta funcion:

   ..src > elisp
     (defun imprimir-cuerpo-grafico (lista-de-numeros)
       "documentacion…"
       (let ((altura  …
              …))

         (while lista-de-numeros
           insertar-columna-y-reposicionar-punto
           (setq lista-de-numeros (cdr lista-de-numeros)))))
   < src..

   Necesitamos completar los espacios de la plantilla.

   Claramente, podemos usar la expresión @c{(apply 'max lista-de-numeros)} para
   determinar la altura del grafico.

   El bucle @c{while} recorrera la @c{lista-de-numeros} un elemento a la vez. A
   medida que se acorta la lista por la expresión @c{(setq lista-de-numeros (cdr
   lista-de-numeros))}, el @c{car} de cada instancia de la lista es el valor del
   argumento para @c{columna-del-grafico}.

   En cada ciclo del bucle @c{while}, la función @c{insert-rectangle} inserta
   la lista devuelta por @c{columna-del-grafico}. Dado que la función
   @c{insert-rectangle}, mueve el punto a la parte inferior derecha del
   rectangulo insertado, necesitamos guardar la ubicacion del punto en el
   momento que se inserta el rectángulo, volver a esta posición después
   de insertar el rectángulo, y despues moverlo horizontalmente al
   siguiente lugar donde se llama a @c{insert-rectangle}.

   Si las columnas insertadas tienen un carácter de ancho, como será si se
   utilizan espacios y asteriscos unicos, el comando de reposicionamiento
   consiste solamente en @c{(forward-char 1)}; sin embargo, el ancho de una
   columna puede ser mayor que uno. Esto significa que el comando de
   reposicionamiento debe escribirse @c{(forward-char ancho-del-simbolo)}. El
   ancho del simbolo en si es la longitud de un grafico en blanco y se puede
   encontrar usando la expresion @c{(length graph-blank)}. El mejor lugar para
   asociar la variable @c{ancho-del-simbolo} al valor de la columna
   de grafico está en la varlist de la expresión @c{let}.

   Estas consideraciones conducen a la siguiente definición de función:

   ..src > elisp
     (defun imprimir-cuerpo-grafico (lista-de-numeros)
       "Imprime un gráfico de barras de la LISTA-DE-NUMEROS.
     La lista-de-numeros esta formada por los valores del eje Y."

       (let ((altura (apply 'max lista-de-numeros))
             (ancho-del-simbolo (length simbolo-en-blanco))
             desde-la-posicion)

         (while lista-de-numeros
           (setq desde-la-posicion (point))
           (insert-rectangle
            (columna-del-grafico altura (car lista-de-numeros)))
           (goto-char desde-la-posicion)
           (forward-char ancho-del-simbolo)
           ;; Dibuja el grafico columna por columna.
           (sit-for 0)
           (setq lista-de-numeros (cdr lista-de-numeros)))
         ;; Coloca el punto para las etiquetas del eje X.
         (forward-line altura)
         (insert "\n")
     ))
   < src..

   La unica expresión inesperada en esta función es @c{(sit-for 0)} dentro del
   bucle @c{while}. Esta expresión hace que la operacion de impresion de
   graficos sea más de lo que sería de otro modo. La expresión hace que Emacs
   @'(pare) @%i(sit) o no haga nada un periodo de tiempo cero y luego vuelva a
   dibujar la pantalla. Puesto aquí, hace que Emacs redibuje la pantalla
   columna por columna. Sin ella, Emacs no redibujaría la pantalla hasta que la
   función termine.

   Podemos probar @c{imprimir-cuerpo-grafico} con una pequeña lista de números.

   1. Instala @c{simbolo-grafico}, @c{simbolo-en-blanco}, @c{columna-del-grafico}, que
      aparecen en las Secciones @l{#Preparar un grafico}, y @c{#La función @c{imprimir-cuerpo-grafico}}.

   2. Copia la siguiente expresión:

      ..src > elisp
        (imprimir-cuerpo-grafico '(1 2 3 4 6 4 3 5 7 6 5 2 3))
      < src..

   3. Cambia al búfer @f{*scratch*} y coloca el cursor donde quieras que empiece
      el grafico.

   4. Pulsa @k{M-:} @%c(eval-expression).

   5. Pega la expresión @c{imprimir-cuerpo-grafico} dentro del minibúfer con
      @k{C-y} @%c(yank).

   6. Presiona @k{RET} para evaluar la expresión @c{imprimir-cuerpo-grafico}.


   Emacs imprimirá un grafico como este:

   ..example >
             *
         *   **
         *  ****
        *** ****
       ********* *
      ************
     *************
   < example..

** La función @c{imprimir-cuerpo-grafico-con-recursividad}

   La función @c{imprimir-cuerpo-grafico} también puede escribirse
   recursivamente. La solución recursiva se divide en dos partes: una
   @'(envoltura) externa que utiliza una expresión @c{let} para determinar los
   valores de varias variables que solo es necesario encontrar una vez, como la
   altura máxima del grafico, y una función interna que se llama recursivamente
   para imprimir el grafico.

   La ‘envoltura’ no es complicada:

   ..src > elisp
     (defun imprimir-cuerpo-grafico-con-recursividad (lista-de-numeros)
       "Imprime un gráfico de barras de la LISTA-DE-NUMEROS.
     La lista-de-numeros esta formada por los valores del eje Y."
       (let ((altura (apply 'max lista-de-numeros))
             (ancho-del-simbolo (length simbolo-en-blanco))
             desde-la-posicion)
         (imprimir-cuerpo-grafico-con-recursividad-interna
          lista-de-numeros
          altura
          ancho-del-simbolo)))
   < src..

   La función recursiva es un poco más difícil. Tiene cuatro partes: la
   ‘prueba-hazlo-de-nuevo’, el código de impresion, la llamada recursiva, y la
   ‘expresion-del-siguiente-paso’. La ‘prueba-hazlo-de-nuevo’ es una expresión
   @c{when} que determina si la @c{lista-de-numeros} contiene algun elemento
   restante; si lo tiene, la función imprime una columna del grafico usando el
   código de impresion y se vuelve a llamar asi misma. La función se llama así
   misma de acuerdo al valor producido por la ‘expresion-del-siguiente-paso’
   que hace que la llamada actue sobre una versión mas corta de la
   @c{lista-de-numeros}.

   ..src > elisp
     (defun imprimir-cuerpo-grafico-con-recursividad-interna
       (lista-de-numeros altura ancho-del-simbolo)
       "Imprime un gráfico de barras.
     Se utiliza dentro del cuerpo de la función imprimir-cuerpo-grafico-con-recursividad."

       (when lista-de-numeros
             (setq desde-la-posicion (point))
             (insert-rectangle
              (columna-del-grafico altura (car lista-de-numeros)))
             (goto-char desde-la-posicion)
             (forward-char ancho-del-simbolo)
             (sit-for 0)     ; Dibuja el gráfico columna por columna.
             (imprimir-cuerpo-grafico-con-recursividad-interna
              (cdr lista-de-numeros) altura ancho-del-simbolo)))
   < src..

   Podemos probar esta expresión después de instalarla; aquí hay un ejemplo:

   ..src > elisp
     (imprimir-cuerpo-grafico-con-recursividad '(3 2 5 6 7 5 3 4 6 4 3 2 1))
   < src..

   Aquí está el resultado:

   ..example >
         *
        **   *
       ****  *
       **** ***
     * *********
     ************
     *************
   < example..

   Cada una de estas dos funciones, @c{imprimir-cuerpo-grafico} o
   @c{imprimir-cuerpo-grafico-con-recursividad}, crea el cuerpo de un grafico.

** Necesidad de Ejes Impresos

   Un grafico necesita ejes impresos para poder orientarse. Para un
   proyecto de usar una vez, puede ser razonable dibujar los ejes a mano usando
   el modo Picture de emacs, pero una funcion de dibujo de graficos puede usarse
   más de una vez.

   Por esta razón, he escrito mejoras a la función básica
   @c{print-graph-body} que imprime automáticamente etiquetas para los ejes
   horizontal y vertical. Como las funciones de impresion de etiquetas no
   contiene mucho material nuevo, he puesto su descripción en un
   apéndice. Ver Seccion @l{#Apéndice C: Un grafico con ejes etiquetados}.

** Ejercicio

   Escribe una versión de grafico de lineas de las funciones de impresión de
   graficos.

* Tu fichero @f{.emacs}

  “No te tiene que gustar Emacs para que te guste”––esta declaracion
  aparentemente paradójica es el secreto de GNU Emacs. En realidad, Emacs es una
  herramienta genérica. La mayoría de las personas que lo usan, lo personalizan
  para ajustarlo a sus necesidades.

  GNU Emacs está escrito principalmente en Emacs Lisp; esto significa que
  escribiendo expresiones en Emacs Lisp se puede modificar o extender Emacs.

  Hay quienes aprecian la configuración por defecto de Emacs. Después de todo,
  Emacs inicia en modo C cuando se edita un fichero C, inicia en modo Fortran
  cuando se edita un fichero Fortran, y en modo Fundamental cuando se edita un
  fichero sin adornos. Esto tiene sentido, si no sabes quien va a utilizar
  Emacs. ¿Quién sabe lo que una persona espera hacer con un fichero sin adornos?
  Para dicho fichero, el modo fundamental es el modo por defecto apropiado, de
  la misma manera C es el modo predeterminado correcto para editar código
  C. (Hay suficientes lenguajes de programación con sintaxis que permiten
  compartir funcionalidades, por lo que el modo C ahora se proporciona para el
  modo CC, ‘C Collection’.)

  Pero cuando sabes quien va a utilizar Emacs––tu mismo––entonces
  tiene sentido personalizar Emacs.

  Por ejemplo, rara vez quiero el modo Fundamental cuando edito un
  fichero que de otro modo no se distinguiria; quiero el modo Text. Por eso
  personalizo Emacs: para que se adapte a mí.

  Puedes personalizar y ampliar Emacs escribiendo o adaptando un fichero
  @f{~/.emacs}. Este es tu fichero de inicialización personal; su
  contenido, escrito en Emacs Lisp, le indica a Emacs qué hacer.@n{14}

  Un fichero @f{~/.emacs} contiene código Emacs Lisp. Puedes escribir este
  código tu mismo; o usar la funcion de Emacs @c{customize} para
  que escriba el código por ti. Puedes combinar tus propias expresiones y
  expresiones auto-escritas en tu fichero @f{.emacs}.

  (Yo prefiero escribir mis propias expresiones, excepto aquellas,
  particularmente las fuentes, que encuentro mas fáciles de manipular usando el
  comando @c{customize}. Combino los dos métodos.)

  La mayor parte de este capítulo trata sobre como escribir expresiones por uno
  mismo. Describe un fichero @f{.emacs} simple; para más información, consulta la Sección
  @l{emacs.html#Init File<>El fichero de inicio} en @e(El Manual de GNU Emacs),
  y la Seccion @l{elisp.html#Init File<>El fichero de inicio} en @e(El Manual de
  Referencia GNU Emacs Lisp).

** Ficheros de inicialización site-wide

   Además de tu fichero de inicialización personal, Emacs carga automáticamente
   varios ficheros de inicialización, si existen. Estos tienen la misma forma
   que tu fichero @f{.emacs}, pero se cargan para todos.

   Dos ficheros de incialización para todos los usuarios, @f{site-load.el} y
   @f{site-init.el}, se cargan en Emacs y luego se @'(vuelcan) si se crea una
   version @'(volcada) de Emacs, como es más común. (Las copias volcadas de
   Emacs se cargan más rápidamente. Sin embargo, una vez que un fichero se carga
   y vuelca, un cambio en el no conduce a un cambio en Emacs a menos que lo
   cargues por tu cuenta. Consulta la Seccion @l{elisp.html#Building
   Emacs<>Construyendo Emacs} en @e(El Manual de Referencia de GNU Emacs Lisp), y
   el fichero @f{INSTALL)}

   Otros tres ficheros de inicialización se cargan automáticamente cada
   vez que se inicia Emacs, si existen. Son @f{site-start.el}, que se carga
   @e{antes} que tu fichero @f{.emacs}, y @f{default.el}, y el fichero de tipo de
   terminal, que se cargan @e{después} de @f{.emacs}.

   Las configuraciones y definiciones en tu fichero @f{.emacs} sobreescribirán
   las configuraciones y definiciones conflictivas del fichero @f{site-start.el},
   si existe; pero las configuraciones y definiciones en @f{default.el} o el
   fichero de tipo de terminal sobreescribirán las de @f{.emacs}. (puede
   evitar las interferencias del fichero de tipo de terminal configurando
   @c{term-file-prefix} a @c{nil}. Consulta la Seccion @l{#Una extensión simple:
   @c{linea-a-lo-alto-de-la-ventana}}.)

   El fichero @f{INSTALL} que viene en la distribución contiene descripciones
   de los ficheros @f{site-init.el} y @f{site-load.el}.

   Los ficheros @f{loadup.el}, @f{startup.el}, y @f{loaddefs.el} controlan la
   carga. Estos ficheros están en el directorio @f{lisp} de la distribución
   Emacs y vale la pena leerlos.

   El fichero @f{loaddefs.el} contiene muchas sugerencias sobre que poner en tu
   propio fichero @f{.emacs}, o dentro de un fichero de inicialización amplio.

** Especificar variables usando @c{defcustom}

   Puedes especificar variables usando @c{defcustom} para que tu y otros puedan
   usar la caracteristica de Emacs @c{customize} para establecer sus valores.
   (No se puede usar @c{customize} para escribir definiciones de función; pero
   se pueden escribir @c{defuns} en el fichero @f{.emacs}. De hecho, se puede
   escribir cualquier expresión Lisp en el fichero @f{.emacs}).

   La caracteristicas de configuracion ofrecidas por @c{customize} dependen de la
   forma especial @c{defcustom}. Aunque se puede usar @c{defvar} o @c{setq} para
   las variables que establecen los usuarios, la forma especial @c{defcustom} está
   diseñada para este trabajo.

   Puedes usar tu conocimiento de @c{defvar} para escribir los primeros
   tres argumentos de @c{defcustom}. El primer argumento de @c{defcustom}
   es el nombre de la variable. El segundo argumento es el valor inicial de
   la variable, si lo hay; y este valor se asigna solo si el valor no se ha
   establecido. El tercer argumento es la documentación.

   El cuarto y subsiguientes argumentos de @c{defcustom} especifican
   tipos y opciones; estos no se presentan en @c{defvar}. (Estos
   argumentos son opcionales.)

   Cada uno de estos argumentos consiste de una palabra clave seguida de un
   valor. Cada palabra clave empieza con el caracter dos puntos @'{:}.

   Por ejemplo, la variable de opciones personalizable @c{text-mode-hook} tiene
   el siguiente aspecto:

   ..src > elisp
     (defcustom text-mode-hook nil
       "El hook normal se ejecuta cuando se ingresa en modo texto y en muchos modos relacionados."
       :type 'hook
       :options '(turn-on-auto-fill flyspell-mode)
       :group 'wp)
   < src..

   El nombre de la variable es @c{text-mode-hook}; no tiene valor por
   defecto; y su cadena de documentación cuenta lo que hace.

   La palabra clave @c{:type} le indica a Emacs el tipo de datos a los que
   @c{text-mode-hook} sera asignado y como mostrar el valor en un búfer
   de personalización.

   La palabra clave @c{:options} especifica una lista sugerida de valores para
   la variable. Normalmente, @c{:options} se asocia a un @"(gancho)
   @%i(hook). La lista es solo una sugerencia; no es excluyente; una persona que
   establece la variable puede establecerla en otros valores; la lista que se
   muestra despues de la palabra clave @c{:options} tiene la intencion de
   ofrecer opciones convenientes a el usuario.

   Finalmente, la palabra clave @c{:group} indica al comando de Personalización
   de Emacs en que el grupo se encuentra la variable. Esto dice dónde encontrala.

   La función @c{defcustom} reconoce más de una docena de palabras clave. Para
   obtener más información, consulta la Seccion @l{elisp.html#Customization<>Escribir
   las Definiciones de Personalización} en @e(El Manual de Referencia GNU Emacs
   Lisp).

   Considera @c{text-mode-hook} como un ejemplo.

   Hay dos maneras de personalizar esta variable. Puedes utilizar el comando
   de personalización o escribir las expresiones apropiadas por tu cuenta.

   Utilizando el comando de personalización, puedes escribir:

   ..example >
     M-x customize
   < example..

   y encontrar que el grupo para editar ficheros de datos se llama
   ‘data’. Introduce este grupo. El Gancho del Modo Text es el primer
   miembro. Puedes hacer click en sus varias opciones, como
   @c{turn-on-auto-fill}, para establecer los valores. Después de hacer click en
   el botón.

   ..example >
     Guárdar para sesiones futuras
   < example..

   Emacs escribirá una expresión en tu fichero @f{.emacs}. Se vera asi:

   ..src > elisp
     (custom-set-variables
       ;; custom-set-variables fué añadido por Custom.
       ;; Si lo editas a mano, podrías estropearlo, así que ten cuidado.
       ;; Tu fichero init deberia contener solo una de esta instancia.
       ;; Si hay más de una, no funcionara bien.
      '(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify))))
   < src..

   (La función @c{text-mode-hook-identify} le indica a
   @c{toggle-text-mode-auto-fill} que buffers estan en modo Texto. Se encendera
   automáticamente)

   La función @c{custom-set-variables} funciona de una manera algo distinta a
   @c{setq}. Aunque nunca he aprendido las diferencias, modifico las expresiones
   @c{custom-set-variable} en mi fichero @f{.emacs} a mano: Hago los cambios de
   la forma que me parecen razonables y no he tenido ningun problema. Otros
   prefieren usar el comando de Personalización y dejar que Emacs haga el
   trabajo por ellos.

   Otra función de @c{custom-set-…} es @c{custom-set-faces}. Esta función
   establece varios tipos de fuentes. Con el tiempo, he asignado un considerable
   número de fuentes. Algunas veces, las reseteo usando @c{customize}; otras
   veces, simplemente edito la expresión @c{custom-set-faces} en mi fichero
   @f{.emacs}.

   La segunda forma de personalizar @c{text-mode-hook} es configurarlo
   directamente en tu fichero @f{.emacs} usando código que no tiene nada que
   ver con las funciones @c{custom-set-…}.

   Al hacer esto, y mas tarde usar @c{customize}, verás un mensaje que
   dice:

   ..example >
     CAMBIADO fuera de Customize; operar con el aquí puede no ser confiable.
   < example..

   Este mensaje es solo una advertencia. Si se cliquear en el botón

   ..example >
     Guárdar para sesiones futuras
   < example..

   Emacs escribirá una expresión @c{custom-set-…} cerca del fin de tu fichero
   @f{.emacs} que será evaluada después de la expresión escrita a mano. Por
   lo tanto, invalidará tu expresión escrita a mano. No se hara ningún daño.
   Sin embargo, cuando hagas esto, ten cuidado para recordar que expresión
   está activa; si lo olvidas, puedes confundirte.

   Siempre y cuando recuerdes donde estan establecidos los valores, no habrá
   ningun problema. En cualquier caso, los valores siempre se establecen en tu
   fichero de inicialización, que suele llamarse @f{.emacs}.

   Yo mismo casi nunca uso @c{customize}. Mayoritariamente,
   escribo las expresiones por mí cuenta.

   Por cierto, para ser mas completo con respecto a las definiciones:
   @c{defsubst} define una función inline. La sintaxis es igual a la de
   @c{defun}. @c{defconst} define un símbolo como una constante. La intencion
   es que ni los programas ni los usuarios cambien nunca un valor establecido por
   @c{defconst}. (Puede cambiarse; el valor se asigna a una variable; pero
   por favor no lo hagas.)

** Empieza por un fichero @f{.emacs}

   Cuando inicia Emacs, carga tu fichero @f{.emacs} a menos que se indique
   que no lo haga especificando @c{-q} en la línea de comandos. (El comando @${emacs
   -q} te da un Emacs limpio, y listo para usar.)

   Un fichero @f{.emacs} contiene expresiones Lisp. Con frecuencia, no son
   más que expresiones para establecer valores; algunas veces son
   definiciones de funcion.

   Consulta la Seccion @l{emacs.html#Init File<>El Fichero de Inicio @f{~/.emacs}} en
   @e(El Manual de GNU Emacs), para una breve descripción de los fichero de
   inicialización.

   Este capítulo pasa por el mismo terreno, pero es un paseo entre extractos
   de un fichero @f{.emacs} completo––el mio.

   La primera parte del fichero consiste en comentarios: recordatorios a mí
   mismo. Por ahora, por supuesto, recuerdo estas cosas, pero cuando empecé, no
   lo hice.

   ..src > elisp
     ;;;; fichero .emacs de Bob
     ; Robert J. Chassell
     ; 26 de Septiembre de 1985
   < src..

   ¡Mira esa fecha! Empecé este fichero hace mucho tiempo. Lo he
   estado extendiendo desde entonces.

   ..src > elisp
     ; Cada sección en este fichero se inicia por una
     ; línea empezando con cuatro punto y coma y cada
     ; entrada inicia por una línea empezando con
     ; tres punto y coma.
   < src..

   Esto describe las convenciones habituales para comentarios en Emacs
   Lisp. Todo lo que aparece en una línea despues de un punto y coma es un
   comentario. Se utilizan dos, tres, y cuatro punto y coma como marcadores de
   subsección y sección. (Consulta la Seccion @l{elisp.html#Comments<>Comentarios} en @e(El
   Manual de Referencia GNU Emacs Lisp), para más informacion sobre los comentarios.)

   ..src > elisp
     ;;;; La Tecla de Ayuda
     ; Control-h es la tecla de ayuda;
     ; después de escribir control-h, escribe una letra
     ; para indicar el asunto sobre el que quieres ayuda.
     ; Para una explicación de la propia ayuda,
     ; escribe control-h dos veces seguidas.
   < src..

   Solo recuerda: escribe @k{C-h} dos veces para pedir ayudar.

   ..src > elisp
     ; Para conocer cualquier modo, presiona control-h m
     ; mientras estés en ese modo. Por ejemplo, para conocer
     ; sobre del modo correo, ingresa al modo correo y luego
     ; presiona control-h m.
   < src..

   El ‘Modo ayuda’, como yo lo llamo, es muy útil. Usualmente, dice todo lo que
   se necesita saber.

   Por supuesto, no necesitas incluir comentarios como estos en tu fichero
   @f{.emacs}. Yo los incluí en el mío porque siempre me olvidaba del Modo ayuda
   o las convenciones para los comentarios––pero pude recordarlos recordármelo a mí
   mismo.

** Modos Text y Auto Fill

   Ahora llegamos a la parte que ‘activa’ al modo Text y el modo Auto Fill.

   ..src > elisp
     ;;; Modo Text y modo Auto Fill
     ;; Las siguiente dos líneas ponen a en Emacs en modo Text
     ;; y en el modo Auto Fill, y son para escritores que
     ;; quieren empezar a escribir en prosa en lugar de código.
     (setq-default major-mode 'text-mode)
     (add-hook 'text-mode-hook 'turn-on-auto-fill)
   < src..

   ¡Aquí está la primera parte de este fichero @f{.emacs} que hace algo
   ademas de ayudarle a recordar a un humano olvidado!

   La primera de las dos líneas entre paréntesis le indican a Emacs que active el
   modo Text cuando se encuentra un fichero, @e{a menos que} ese fichero
   este en algún otro modo, por ejemplo, el modo C.

   Cuando Emacs lee un fichero, examina la extensión del nombre del fichero. (La
   extensión es la parte que esta después de un @'{.}.) Si el fichero finaliza
   con una extensión @'{.c} o @'{.h} entonces Emacs activa el modo C. Ademas,
   Emacs examina la primer línea no en blanco del fichero; si la línea dice
   @'{-*- C -*-}, Emacs activa el modo C. Emacs posee una lista de extensiones y
   especificaciones que usa automáticamente. Además, Emacs busca cerca de la
   última página por buffer una “lista variables locales”, si la hay.

   Consulta las secciones @l{emacs.html#Choosing Modes<>Cómo se Eligen
   los Modos Mayores} y @l{emacs.html#File Variables<>Variables Locales en Ficheros}
   en @e{El Manual de GNU Emacs}.

   Ahora, volvamos al fichero @f{.emacs}.

   Aquí está la línea de nuevo; ¿cómo funciona?

   ..src > elisp
     (setq major-mode 'text-mode)
   < src..

   Esta corta línea es una expresion Lisp.

   Ya estamos familiarizados con @c{setq}. Esto establece la siguiente variable,
   @c{major-mode}, al valor subsiguiente, que es @c{text-mode}. La comilla
   simple antes de @c{text-mode} le indica a Emacs que trate directamente con el
   símbolo @c(text-mode), no con lo que pueda significar. Consulta la Seccion
   @l{#Establecer el Valor de una Variable}, para recordar como funciona @c{setq}.
   El punto principal es que no hay diferencia entre el procedimiento
   que se usa utiliza para establecer un valor en tu fichero @f{.emacs} y el procedimiento
   que se usa en cualquier otro lugar de Emacs.

   Aquí está la siguiente línea:

   ..src > elisp
     (add-hook 'text-mode-hook 'turn-on-auto-fill)
   < src..

   En esta línea, el comando @c{add-hook} añade @c{turn-on-auto-fill} a la
   variable.

   ¡@c{turn-on-auto-fill} es el nombre de un programa, que lo adivinaste!,
   activa el modo Auto Fill.

   Cada vez que Emacs activa el modo Text, Emacs ejecuta los comandos ‘hooked’
   @%i(conectados) al modo Text. Por lo tanto, cada vez que Emacs activa el
   modo Text, Emacs también activa el modo Auto Fill.

   En resumen, la primer línea hace que Emacs entre en modo Text cuando se
   edita un fichero, a menos que la extensión del nombre del fichero, una
   primer línea no en blanco o variables locales le indiquen lo contrario.

   El modo Text entre otras acciones, establece la tabla de sintaxis para
   trabajar adecuadamente a los escritores. En el modo Text, Emacs considera un
   apóstrofe como parte de una palabra como una letra; pero Emacs no
   considera un punto o un espacio como parte de una palabra. De este modo,
   @k{M-f} se mueve a través de @'{d'Alcañiz}. Por otro lado, en el modo C,
   @k{M-f} se detiene justo despues de la @'{d} de @'{d'Alcañiz}.

   La segunda línea hace que Emacs active el modo Auto Fill cuando cambia al
   modo Text. En el modo Auto Fill, Emacs rompe automáticamente una línea
   que es demasiado ancha y mueve la parte exedente a la siguiente línea. Emacs
   rompe las líneas entre palabras, no dentro de ellas.

   Cuando el modo Auto Fill está desactivado, las líneas continúan hacia la
   derecha a medida que se escriben. Dependiendo de como se establece el valor de
   @c{truncate-lines}, las palabras que escribas desaparecen del lado
   derecho de la pantalla, o bien se mostraran, de una manera bastante fea e
   ilegible, como una línea continua en la pantalla.

   Además, en esta parte de mi fichero @f{.emacs}, le digo a los comandos de
   relleno que inserten dos espacios después de dos puntos:

   ..src > elisp
     (setq colon-double-space t)
   < src..

** Alias de correo

   Aquí hay un @c{setq} que ‘activa’ el alias de correo, junto con mas recordatorios.

   ..src > elisp
     ;;; Modo Correo
     ; Para entrar en el modo correo, presiona ‘C-x m’
     ; Para entrar en RMAIL (para leer el correo),
     ; presiona ‘M-x rmail’
     (setq mail-aliases t)
   < src..

   Este comando @c{setq} asigna el valor de la variable @c{mail-aliases} a
   @c{t}. Ya que @c{t} significa verdadero, la línea dice, “Sí, usa
   alias de correo.”

   Los alias de correo son nombres cortos convenientes para direcciones
   de correo largas o para listas de direcciones de correo. El fichero
   donde guardas tus ‘aliases’ es @f{~/.mailrc}. Se escribe un alias como
   este:

   ..example >
     alias geo george@foobar.wiz.edu
   < example..

   Cuando escribas un mensaje a Jorge, envialo a la dirección @'{geo}; el correo
   automáticamente expandirá @'{geo} a la dirección completa.

** Modo Indent Tabs

   Por defecto, Emacs inserta tabulaciones en lugar en espacios múltiples
   cuando se da formato a una región. (Por ejemplo, se podrían indentar muchas
   líneas de texto a la vez con el comando @c{indent-region}.) Los
   tabuladores se ven bien en un terminal o con impresión ordinaria, pero
   producen una salida mal indentada cuando se usa T@_(E)X o Texinfo
   ya que T@_(E)X ignora los tabuladores.

   Lo siguiente desactiva el modo de Indent Tabs:

   ..src > elisp
     ;;; Prevenir Tabulaciones Extrañas
     (setq-default indent-tabs-mode nil)
   < src..

   Observa que esta línea usa @c{setq-default} en vez de el comando @c{setq} que
   hemos visto antes. El comando @c{setq-default} asigna valores solo en
   búfers que no tienen sus propios valores locales para la variable.

   Consulta las secciones @l{emacs.html#Just Spaces<>Tabuladores versus Espacios} y
   @l{emacs.html#File Variables<>Variables Locales en Ficheros} en @e{El Manual
   de GNU Emacs}.

** Algunos Atajos de teclado

   Ahora algunos atajos personales:

   ..src > elisp
     ;;; Compara ventanas
     (global-set-key "\C-cw" 'compare-windows)
   < src..

   @c{compare-windows} es un comando excelente que compara el texto de la
   ventana actual con el texto de la siguiente ventana. Realiza la comparación
   empezando en el punto en cada ventana, moviendose a través del texto en cada
   ventana en la medida en que coincidan. Uso este comando todo el tiempo.

   Esto también muestra como configurar una atajo globalmente, para todos los
   modos

   El comando es @c{global-set-key}. Va seguido por el atajo de teclado. En un fichero
   @f{.emacs}, el atajo se escribe como se muestrta: @c{\C-c} significa
   ‘control-c’, lo que significa ‘presionar la tecla de control y la tecla @k{c}
   al mismo tiempo’. La @c{w} significa ‘presionar la tecla @k{w}’. El atajo esta
   rodeado por comillas dobles. En el atajo, se presionaria esto como @k{C-c
   w}. (Si estuvieras enlazando una tecla @k{META}, como @k{M-c}, en lugar de la
   tecla @k{CTRL}, se escribiría @c{\M-c} en el fichero @f{.emacs}. Consulta la
   Seccion @l{emacs.html#Init Rebinding<>Teclas de atajos en tu fichero Init}
   en @e(El Manual de GNU Emacs), para más detalles.)

   El comando invocado por las teclas es @c{compare-windows}. Observa que
   @c{compare-windows} es precedido por una comilla simple; de otro modo,
   Emacs intentaría primero evaluar el símbolo para determinar su valor.

   Estas tres cosas, las comillas dobles, la barra invertida antes
   de la @'{C}, y la comilla simple son partes necesarias en los atajos
   de teclado que tiendo a olvidar. Afortunadamente, he llegado a recordarlo
   mirando mi fichero @f{.emacs}, y adaptando lo que hay alli.

   En cuanto al atajo: @k{C-c w}, combina la tecla prefija, @k{C-c},
   con un caracter simple, en este caso, @k{w}. Este conjunto de teclas,
   @k{C-c} seguido por un solo caracter, esta estrictamente reservado para
   uso individual. (Llamo a estas teclas ‘propias’, ya que son
   para mi propio uso). Siempre debes ser capaz de crear un atajo de este tipo para
   tu propio uso sin pisar el atajo de otra persona. Si alguna vez escribes una
   extensión a Emacs, por favor, evita tomar cualquiera de estos atajos para
   uso público. Crea un combinacion @k{C-c C-w} en su lugar. De lo contrario,
   nos quedaremos sin atajos ‘propios’.

   Aquí hay otro atajo, con un comentario:

   ..src > elisp
     ;;; Atajo para ‘occur’
     ; Uso mucho occur, así que voy a asignarlo a un atajo:
     (global-set-key "\C-co" 'occur)
   < src..

   El comando @c{occur} muestra todas las líneas en el buffer actual que
   contiene una coincidencia para una expresión regular. Las líneas que
   coinciden se muestran en un búfer llamado @f{*Occur*}. Esse buffer sirve como
   un menu para saltar a las ocurrencias.

   Aquí se muestra como desasignar un atajo, para que no funcione:

   ..src > elisp
     ;;; Desasociar ‘C-x f’
     (global-unset-key "\C-xf")
   < src..

   Hay una razón para esto: Encuentro que inadvertidamente presiono @k{C-x f} en
   lugar de @k{C-x C-f}. En lugar de encontrar un fichero, como pretendia,
   accidentalmente asigno el ancho del modo Auto Fill, casi siempre a un
   tamaño que no quería. Como casi nunca reseteó mi ancho por defecto,
   simplemente desvinculo el atajo.

   Lo siguiente reasocia un atajo existente:

   ..src > elisp
     ;;; Reasocia ‘C-x C-b’ a ‘buffer-menu’
     (global-set-key "\C-x\C-b" 'buffer-menu)
   < src..

   Por defecto, @k{C-x C-b} ejecuta el comando @c{list-buffers}. Este comando
   lista tus buffers en @e{otra} ventana. Como casi siempre quiero hacer algo en
   esa ventana, prefiero el comando @c{buffer-menu}, que no solo lista los
   buffers, sino que tambien mueve el punto a esa ventana.

** Mapas de teclado

   Emacs usa @:{keymaps} para registrar qué teclas llaman a qué comandos. Cuando
   se usa @c{global-set-key} para asignar los atajos de teclado a un unico
   comando en todas las partes de Emacs, se esta especificando el atajo en el
   @c{current-global-map}.

   Los Modos específicos, como el modo C o el modo Texto, tiene sus propios
   mapas de teclado; los mapas de teclado específico del modo sobreescriben el
   mapa global que comparten todos los buffers.

   La función @c{global-set-key} asocia, o reasocia, el mapa de teclas
   global. Por ejemplo, lo siguiente vincula el atajo @k{C-x C-b} a la
   función @c{buffer-menu}:

   ..src > elisp
     (global-set-key "\C-x\C-b" 'buffer-menu)
   < src..

   Los Mapas de teclado específicos de un modo se vinculan mediente la función
   @c{define-key}, que toma un mapa de teclado específico como un argumento,
   asi como el atajo y el comando. Por ejemplo, mi fichero @f{.emacs}
   contiene la siguiente expresión para vincular el comando
   @c{texinfo-insert-@@group} a @k{C-c C-c g}:

   ..src > elisp
     (define-key texinfo-mode-map "\C-c\C-cg" 'texinfo-insert-@group)
   < src..

   La función @c{texinfo-insert-@@group} en si misma es una pequeña extensión del
   modo Texinfo que inserta @'{@@group} dentro de un fichero Texinfo. Utilizo
   este comando todo el tiempo y prefiero escribir los tres atajos @k{C-c
   C-c g} en vez de los seis caracteres @k{@@ g r o u p}. (@'{@@group} y su
   acompañante @'{@@end group} son comandos que mantienen todo el texto que encierran
   en una página; muchos ejemplos multi-línea en este libro están
   rodeados por @'{@@group … @@end group}.)

   Aquí está la definición de la función @c{texinfo-insert-@@group}:

   ..src > elisp
     (defun texinfo-insert-@group ()
       "Inserta la cadena @group en un búfer Texinfo."
       (interactive)
       (beginning-of-line)
       (insert "@group\n"))
   < src..

   (Por supuesto, podría haber usado el modo Abbrev para evitar la fatiga de
   escribir, en vez de crear una función para insertar una palabra; pero
   prefiero tener atajos de teclado coherentes con otros atajos del modo Texinfo.)

   Verás numerosas expresiones @c{define-key} en @f{loaddefs.el} asi como en las
   diversas librerias de los modos, como @f{cc-mode.el} y @f{lisp-mode.el}.

   Para más información sobre los mapas de teclado, consulta la Seccion
   @l{emacs.html#Key Bindings<>Personalizando Atajos de Teclado} en @e(El Manual
   de GNU Emacs), y la Seccion @l{elisp.html#Keymaps<>Mapas de Teclado} en @e(El
   Manual de Referencia de GNU Emacs Lisp).

** Cargando ficheros

   Muchas personas en la comunidad de GNU Emacs han escrito extensiones para
   Emacs. Con el paso del tiempo, estas extensiones a menudo se incluiyen en
   las nuevas versiones. Por ejemplo, los paquetes Calendar y
   Diary son ahora parte del GNU Emacs estándar, como lo es Calc.

   Se puede usar el comando @c{load} para evaluar un fichero completo y, por lo
   tanto, instalar todas las funciones y variables del fichero en Emacs. Por
   ejemplo:

   ..src > elisp
     (load "~/emacs/slowsplit")
   < src..

   Esto evalúa, es decir, carga, el fichero @f{slowsplit.el} o si existe,
   el fichero compilado mas rapido @f{slowsplit.elc}, desde el
   subdirectorio @f{emacs} en tu directorio home. El fichero contiene la
   función @c{split-window-quietly}, que John Robinson escribió en 1989.

   La función @c{split-window-quietly} divide una ventana con el mínimo de
   redisplay. La instalé en 1989 porque funcionaba bien con los viejos
   terminales de 1200 baudios que usaba entonces. Hoy en dia, solo de vez en
   cuando me encuentro con una conexión tan lenta, pero sigo usando la función
   porque me gusta la forma en que deja la mitad inferior de un búfer en la
   parte inferior de la nueva ventana y la mitad superior en la ventana superior.

   Para reemplazar el atajo de teclado por defecto de
   @c{split-window-vertically}, se debe desactivar ese atajo y
   asociarlo de nuevo a @c{split-window-quietly}, asi:

   ..src > elisp
     (global-unset-key "\C-x2")
     (global-set-key "\C-x2" 'split-window-quietly)
   < src..

   Si cargas muchas extensiones, como yo, entonces en lugar de
   especificar la ubicacion exacta del fichero de extencion, como se muestra arriba, se
   puede especificar el directorio como la funcion @c{load-path} de
   Emacs. En ese caso, cuando Emacs carga un fichero, buscará en ese directorio asi
   como en la lista predeterminada de directorios. (La lista predeterminada se
   especificada en @f{paths.h} cuando se construye Emacs.)

   El siguiente comando añade tu directorio @f{~/emacs} a la ruta de carga existente:

   ..src > elisp
     ;;; Ruta de carga Emacs
     (setq load-path (cons "~/emacs" load-path))
   < src..

   Por cierto, @c{load-library} es una interfaz interactiva para la función
   @c{load}. La función tiene el siguiente aspecto:

   ..src > elisp
     (defun load-library (library)
       "Carga la librería llamada LIBRARY.
     Esta es una interfaz para la función ‘load’."
       (interactive
        (list (completing-read "Carga la librería: "
                               (apply-partially 'locate-file-completion-table
                                                load-path
                                                (get-load-suffixes)))))
       (load library))
   < src..

   El nombre de la función, @c{load-libray}, proviene del uso de ‘library’
   como un sinónimo convencional de ‘fichero’. El codigo del comando @c{load-library}
   está en la librería @f{files.el}.

   Otro comando interactivo que hace un trabajo ligeramente diferente es
   @c{load-file}. Consulta la Seccion @l{emacs.html#Lisp Libraries<>Librerías de
   Código Lisp para Emacs} en @e(El Manual de GNU Emacs), para obtener
   información sobre la diferencia entre @c{load-library} y este comando.

** Autocarga

   En lugar de instalar una función cargando el fichero que la contiene, o
   evaluando la definición de función, puedes hacer que la función este disponible
   pero no instalarla hasta que se llame por primera vez. Este proceso
   se llama @:{autocarga}.

   Cuando se ejecuta una función de autocarga, Emacs evalúa automáticamente
   el fichero que contiene la definición, y entonces llama a la función.

   Emacs inicia mas rápido con funciones de autocarga, ya que sus librerías no
   se cargan de inmediato; pero es necesario esperar un momento cuando se
   utiliza por primera vez una función de este tipo, mientras se evalua el
   fichero que la contiene.

   Las funciones poco utilizadas con frecuencia se autocargan. La librería
   @f{loaddefs.el} coniene cientos de funciones autocargadas, desde el modo
   @c{bookmark-set} hasta el modo @c{wordstar-mode}. Por supuesto, puedes
   llegar a utilizar una función ‘rara’ con frecuencia, cuando sea asi deberías
   cargar ese fichero de función con una expresión @c{load} en tu fichero
   @f{.emacs}.

   En mi fichero @f{.emacs}, cargo 14 librerías que contienen funciones que de
   otro modo serían autocargadas. (En realidad, hubiera sido mejor incluir estos
   ficheros en mi Emacs ‘volcado’, pero lo olvide. Consulta la Sección
   @l{elisp.html#Building Emacs<>Construyendo Emacs} en @e(El Manual de
   Referencia de GNU Emacs Lisp), y el fichero @f{INSTALL} para más informacion
   acerca del volcado.)

   Tambien puedes querer incluir expresiones de autocarga en tu fichero
   @f{.emacs}. @c{autoload} es una función nativa que toma hasta cinco
   argumentos, los tres ultimos son opcionales. El primer argumento es el nombre
   de la función para autocargar. El segundo es el nombre del fichero a cargar.
   El tercer argumento es la documentación de la función, y el cuarto dice si la
   función puede llamarse de forma interactiva. El quinto argumento es el tipo
   de objeto––@c{autoload} puede manejar un mapa de teclado o macro asi como una
   función (el valor por defecto es una función).

   Aquí hay un ejemplo típico:

   ..src > elisp
     (autoload 'html-helper-mode
       "html-helper-mode" "Editar documentos HTML" t)
   < src..

   (@c{html-helper-mode} es una alternativa mas antigua a @c{html-mode}, que es una
   parte estándar de la distribución.)

   Esta expresión autocarga la función @c{html-helper-mode}. Se toma
   del fichero @f{html-helper-mode-el} (o desde la versión compilada
   @f{html-helper-mode.elc}, si existe). El fichero debe estar ubicado
   en un directorio específicado por @c{load-path}. La documentación dice que
   este es un modo para ayudar a editar documentos escritos en Lenguaje de
   Marcas de Hiper Texto. Puedes llamar a este modo interactivamente
   escribiendo @k{M-x html-helper-mode}. (Se necesita duplicar la documentacion de
   la funcion regular en la expresión de autocarga porque la función
   regular todavia no está cargada, así que su documentación no está disponible.)

   Consulta la Seccion @l{elisp.html#Autoload<>Autocarga} en @e(El Manual de
   Referencia de GNU Emacs Lisp), para más información.

** Una extensión simple: @c{linea-a-lo-alto-de-la-ventana}

   Aquí esta una extensión simple para Emacs que mueve linea donde esta el punto a la
   parte superior de la ventana. Uso esto todo el tiempo, para hacer que el
   texto sea mas fácil de leer.

   Puedes poner el siguiente código dentro de un fichero separado y luego
   cargarlo desde tu fichero @f{.emacs}, o tambien incluirlo en tu fichero
   @f{.emacs}.

   Aquí está la definición

   ..src > elisp
     ;;; Línea a lo alto de la ventana;
     ;;; Reemplaza tres pulsaciones de teclado C-u 0 C-l
     (defun linea-a-lo-alto-de-la-ventana ()
       "Mueve la línea donde esta el punto a lo alto de la ventana."
       (interactive)
       (recenter 0))
   < src..

   Ahora para el atajo.

   Hoy en día, las teclas de función, así como los eventos del ratón y los
   caracteres no @c{ascii} se escriben entre corchetes, sin comillas. (En la
   versión 18 de Emacs y anteriores, se tenían que escribir diferentes
   combinaciones de teclas de función para cada terminal.)

   Vincule @c{linea-a-lo-alto-de-la-ventana} con mi tecla de función @k{F6}
   así:

   ..src > elisp
     (global-set-key [f6] 'linea-a-lo-alto-de-la-ventana)
   < src..

   Para más información, consulta la Seccion @l{emacs.html#Init Rebinding<>Reasociando Teclas
   en tu fichero init} en @e{El Manual de GNU Emacs}.

   Si ejecutas dos versiones de GNU Emacs, como las versiones 22 y 23, y
   usas un fichero @f{.emacs}, puedes seleccionar qué código evalúar con el
   siguiente condicional:

   ..src > elisp
     (cond
      ((= 22 emacs-major-version)
       ;; evalúa el codigo de la version 22
       ( … ))
      ((= 23 emacs-major-version)
       ;; evalúa el codigo de la version 23
       ( … )))
   < src..

   Por ejemplo, en las versiones recientes el cursor parpadea por defecto. Odio
   este tipo de parpadeo, como tambien otras caracteristicas, asi que puse lo
   siguiente en mi fichero @f{.emacs}@n{15}:

   ..src > elisp
     (when (>= emacs-major-version 21)
       (blink-cursor-mode 0)
       ;; Insertar una nueva línea cuando se presiona ‘C-n’ (next-line)
       ;; al fin del búfer
       (setq next-line-add-newlines t)
       ;; Activar la visualizacion de imagenes
       (auto-image-file-mode t)
       ;; Activa la barra de menu (esta barra tiene texto)
       ;; (Usa un argumento numérico para activarlo)
       (menu-bar-mode 1)
        ;; Desactivar la barra de herramientas (esta barra tiene iconos)
        ;; (Usa un argumento numérico para activarlo)
        (tool-bar-mode nil)
       ;; Desactiva el modo de informacion sobre la barra de herramientas
       ;; (Este modo hace que aparezcan explicaciones emergentes en los iconos)
       ;; (Usa un argumento numérico para activarlo)
       (tooltip-mode nil)
       ;; Si las sugerencias estan activadas, hace que aparezcan rapidamente
       (setq tooltip-delay 0.1)  ; por defecto es 0.7 segundos
        )
   < src..

** Colores X11

   Se pueden especificar colores cuando se usa Emacs con el Sistema de
   Ventanas X del MIT.

   No me gustan los colores por defecto y especifico los mios propios.

   Aquí están las expresiones en mi fichero @f{.emacs} que establecen los valores:

   ..src > elisp
     ;; Asigna el color del cursor
     (set-cursor-color "white")

     ;; Asigna el color del ratón
     (set-mouse-color "white")

     ;; Asigna el color del texto y del fondo
     (set-foreground-color "white")
     (set-background-color "darkblue")

     ;;; Asigna colores para el resaltado de busqueda y registros
     (set-face-foreground 'highlight "white")
     (set-face-background 'highlight "blue")

     (set-face-foreground 'region "cyan")
     (set-face-background 'region "blue")

     (set-face-foreground 'secondary-selection "skyblue")
     (set-face-background 'secondary-selection "darkblue")

     ;; Asigna colores al calendario
     (setq calendar-load-hook
           '(lambda ()
              (set-face-foreground 'diary-face   "skyblue")
              (set-face-background 'holiday-face "slate blue")
              (set-face-foreground 'holiday-face "white")))
   < src..

   Las diferentes tonalidades de azul me alivian la vista y me impiden ver el
   parpadeo de la pantalla.

   Alternativamente, podría haber establecido mis especificaciones en
   varios ficheros de inicialización X. Por ejemplo, podría establecer los
   colores del primer plano, fondo, cursor y puntero (es decir, ratón) en mi
   fichero @f{~/.Xresources} de esta manera:

   ..example >
     Emacs*foreground:   white
     Emacs*background:   darkblue
     Emacs*cursorColor:  white
     Emacs*pointerColor: white
   < example..

   En cualquier caso, como no forma parte de Emacs, asigno el color raíz de
   mi ventana X en mi fichero @f{~/.xinitrc}, asi@n{16}

   ..src > sh
     xsetroot -solid Navy -fg white &
   < src..

** Ajustes misceláneos para un fichero @f{.emacs}

   Aquí hay algunos ajustes misceláneas:

   - Asigna la forma y color del cursor del ratón:

     ..src > elisp
       ; Las formas de los cursores se definen en
       ; ‘/usr/include/X11/cursorfont.h’;
       ; por ejemplo, el cursor ‘objetivo’ es el número 128;
       ; el cursor ‘top_left_arrow’ es el número 132.

       (let ((mpointer (x-get-resource "*mpointer"
                                       "*emacs*mpointer")))
         ;; Si no has configurado el puntero del ratón
         ;; configuralo, de lo contrario, dejalo como esta:
         (if (eq mpointer nil)
             (setq mpointer "132")) ; top_left_arrow
         (setq x-pointer-shape (string-to-int mpointer))
         (set-mouse-color "white"))
     < src..

   - O se pueden asignar los valores de una variedad de caracteristicas en
     una lista, como esta:

     ..src > elisp
       (setq-default
        default-frame-alist
        '((cursor-color . "white")
          (mouse-color . "white")
          (foreground-color . "white")
          (background-color . "DodgerBlue4")
          ;; (cursor-type . bar)
          (cursor-type . box)
          (tool-bar-lines . 0)
          (menu-bar-lines . 1)
          (width . 80)
          (height . 58)
          (font . "-Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO8859-1")
          ))
     < src..

   - Convierte @k{CTRL-h} en @k{DEL} y @k{DEL} en @k{CTRL-h}.

     (Algunos teclados viejos necesitan esto, aunque no he visto el problema
     recientemente.)

     ..src > elisp
       ;; Traducir ‘C-h’ a <DEL>.
       ; (keyboard-translate ?\C-h ?\C-?)

       ;; Traducir <DEL> a ‘C-h’.
       (keyboard-translate ?\C-? ?\C-h)
     < src..

   - ¡Desactiva el parpadeo del cursor!

     ..src > elisp
       (if (fboundp 'blink-cursor-mode)
           (blink-cursor-mode -1))
     < src..

     o inicia GNU Emacs con el comando @${emacs -nbc}.

   - Cuando se utiliza @$(grep)

     - @'c{-i}: Ignorar mayusculas o minusculas

     - @'c{-n}: Prefija cada línea de la salida con el número de línea

     - @'c{-H}: Imprime el nombre del fichero para cada coincidencia.

     - @'c{-e}: Protege los patrones que empiezan con un guión, @'c{-}

       ..src > elisp
         (setq grep-command "grep -i -nH -e ")
       < src..

   - Encuentra un búfer existente, incluso si tiene un nombre diferente

     Esto evita problemas con los enlaces simbólicos.

     ..src > elisp
       (setq find-file-existing-other-name t)
     < src..

   - Establece el idioma del entorno y el método de entrada por defecto

     ..src > elisp
       (set-language-environment "latin-1")
       ;; Recuerda que se puede habilitar o deshabilitar la entrada de texto
       ;; multilingüe con el comando @c{toggle-input-method} (C-\)
       (setq default-input-method "latin-1-prefix")
     < src..

     Si quieres escribir con caracteres Chinos ‘GB’, asigna esto:

     ..src > elisp
       (set-language-environment "Chinese-GB")
       (setq default-input-method "chinese-tonepy")
     < src..

*** Corrigiendo Atajos de Teclados desagradables

    Algunos sistemas vinculan las teclas de forma desagradable. Algunas veces,
    por ejemplo, la tecla @k{CTRL} aparece en un lugar incomodo en lugar de en
    el extremo izquierdo de la fila de inicio.

    Normalmente, cuando las gente arregla este tipo de atajos, no
    cambia su fichero @f{~/.emacs}. En su lugar, enlazan asocian las teclas
    apropiadas en la consola con los comandos @${loadkeys} o
    @${install-keymap} en su script de inicio e incluyen comandos
    @${xmodmap} en su fichero @f{.xinitrc} o @f{.Xsession} de X Windows.

    Para un script de inicio:

    ..src > sh
      loadkeys /usr/share/keymaps/i386/qwerty/emacs2.kmap.gz
    < src..

    o

    ..src > sh
      install-keymap emacs2
    < src..

    Para un fichero @f{.xinitrc} o un fichero @f{.Xsession} cuando la tecla
    @k{Bloq Mayus} esta en el extremo izquierdo de la fila de inicio:

    ..src > sh
      # Asocia la tecla ‘Bloq Mayus’ a ‘Control’
      # (Una interfaz de usuario tan rota, sugiere que los fabricantes de teclados
      # piensan que las computadoras son máquinas de escribir de 1885.)

      xmodmap -e "clear Lock"
      xmodmap -e "add Control = Caps_Lock"
    < src..

    En un fichero @f{.xinitrc} o @f{.Xsession}, para convertir una tecla @k{ALT} en
    una tecla @k{META}:

    ..src > sh
      # Algunos teclados mal diseñados tienen una tecla etiquetada ALT y no Meta
      xmodmap -e "keysym Alt_L = Meta_L Alt_L"
    < src..

** Una línea de Modo modificada

   Finalmente, una caracteristica que realmente me gusta: una linea de modo
   modificada.

   Cuando trabajo a través de una red, olvido que máquina estoy usando.
   También, tiendo a perder la nocion de donde estoy, y en que linea esta el punto.

   Así se restableci mi linea de modo para que se viera asi:

   ..example >
     ::-- foo.texi   rattlesnake:/home/bob/  Line 1  (Texinfo Fill) Top
   < example..

   Estoy visitando un fichero llamado @f{foo.texi}, en mi máquina
   @f{rattlesnake} en mi búfer @f{/home/bob}. Estoy en la línea 1, en
   modo Texinfo, y en la parte superior del búfer.

   Mi fichero @f{.emacs} tiene una sección que luce asi:

   ..src > elisp
     ;; Configura una linea de modo que me dice en que máquina, directorio,
     ;; y línea estoy, ademas de la información habitual.
     (setq-default mode-line-format
      (quote
       (#("-" 0 1
          (help-echo
           "mouse-1: seleccionar ventana\nmouse-2: eliminar otras ..."))
        mode-line-mule-info
        mode-line-modified
        mode-line-frame-identification
        "    "
        mode-line-buffer-identification
        "    "
        (:eval (substring
                (system-name) 0 (string-match "\\..+" (system-name))))
        ":"
        default-directory
        #(" " 0 1
          (help-echo
           "mouse-1: seleccionar ventana\nmouse-2: eliminar otras ..."))
        (line-number-mode " Line %l ")
        global-mode-string
        #("   %[(" 0 6
          (help-echo
           "mouse-1: seleccionar ventana\nmouse-2: eliminar otras ..."))
        (:eval (mode-line-mode-name))
        mode-line-process
        minor-mode-alist
        #("%n" 0 2 (help-echo "mouse-2: widen" local-map (keymap ...)))
        ")%] "
        (-3 . "%P")
        ;;   "-%-"
        )))
   < src..

   Aquí, redefino la linea de modo por defecto. La mayoría de las partes son del
   original; pero hago algunos cambios. Estableci el formato de la linea de modo
   por @e{defecto} para permitir que varios modos, como Info, la sobreescriban.

   Muchos elementos de la lista se explican por si mismos: @c{mode-line-modified}
   es una variable que indica si el búfer ha sido modificado, @c{mode-name}
   indica el nombre del modo, y así sucesivamente. Sin embargo, el formato
   parece complicado debido a dos caracteristicas que no hemos discutido.

   La primera cadena en la línea de modo es un guión, @'c(-). En los viejos tiempos,
   se habría especificado simplemente como @c("-"). Pero hoy en día, Emacs puede
   añadir propiedades a una cadena, como resaltado o, en este caso, una
   función de ayuda. Si colocas el cursor del ratón sobre el guión, aparece
   información de ayuda (de forma predeterminada, debe esperar siete décimas de
   segundo antes de que aparezca la información). Puedes cambiar esa
   temporización cambiando el valor de @c{tooltip-delay}.

   El nuevo formato de cadena tiene una sintaxis especial:

   ..src > elisp
     #("-" 0 1 (help-echo "mouse-1: seleccionar ventana\n..."))
   < src..

   El @c{#(} inicia una lista. El primer elemento de la lista es la cadena en
   sí, solo un @'c{-}. El segundo y tercer elemento especifica el rango al que se
   aplica el cuarto elemento. Un rango empieza @e{después} de un carácter, por
   lo que un cero significa que el rango empieza justo después del primer caracter;
   un 1 significa que el rango termina justo después del primer caracter. El
   tercer elemento es la propiedad del rango. Consiste en una lista de
   propiedades, un nombre de propiedad, en este caso, @'c{help-echo}, seguido de
   un valor, en este caso, una cadena. El segundo, tercer y cuarto elemento de
   este nuevo formato de cadena se pueden repetir.

   Para más información, consulta las Secciones @l{elisp.html#Text
   Properties<>Propiedades de Texto} y @l{elisp.html#Mode Line Format<>Formato
   de Linea de Modo} en @e{El Manual de Referencia de GNU Emacs Lisp}.

   @c{mode-line-buffer-identification} muestra el nombre del buffer. Es una
   lista que inicia por @c{(#("%12b" 0 4 …}. El @c{#(} inicia la lista.

   El @'c{"%12b"} muestra el nombre del actual búfer, usando la función
   @c{buffer-name} con la que estamos familiarizados; el @'c(12) especifica el
   número máximo de caracteres que serán mostrados. Cuando un nombre tiene
   pocos caracteres, el espacio en blanco se añade para rellenar este
   número. (Los nombres del búfer pueden y con frecuencia tendran mas de
   12 caracteres; esta longitud funciona bien en una típica ventana de 80
   columnas de ancho.)

   @c{:eval} dice que hay que evaluar la siguiente forma y usar el resultado
   como una cadena para mostrar. En este caso, la expresión muestra el primer
   componente del nombre completo del sistema. El fin del primer componente es
   un @'{.}  (‘punto’), así que uso la función @c{string-match} para contar el
   tamaño del primer componente. La subcadena desde el caracter cero a este
   tamaño es el nombre de la máquina.

   Esta es la expresión:

   ..src > elisp
     (:eval (substring
             (system-name) 0 (string-match "\\..+" (system-name))))
   < src..

   @'c{%[} y @'c{%]} hacen que aparezca un par de corchetes por cada nivel de
   edición recursiva. @'c{%n} indica ‘Reducido’ cuando la reduccion esta en
   efecto. @'c{%P} indica el porcentaje del búfer que está por encima de la
   ventana, o ‘Top’, ‘Bottom’, o ‘All’. (Una @'c{p} minúscula indica el
   porcentaje por encima de la parte superior de la ventana.) @'c{%-} inserta
   suficientes guiones para rellenar la línea.

   Recuerda, “No tiene que gustarte Emacs para que te guste”––Emacs puede tener
   diferentes colores, diferentes comandos y diferentes atajos que el Emacs por
   defecto.

   Por otro lado, si quieres ‘sacar un Emacs de la caja’, sin
   personalización alguna, escribe:

   ..src > sh
     emacs -q
   < src..

   Esto iniciara un Emacs que @e{no} cargue tu fichero de inicializacion
   @f{~/.emacs}. Un Emacs normal y corriente. Nada más.

* Depurancion

  GNU Emacs tiene dos depuradores, @c{debug} y @c{edebug}. El primero esta
  incorporado nativamente dentro de Emacs y siempre está contigo; el segundo
  requiere que escribas una función antes de poder usarlo.

  Ambos depuradores se describen extensivamente en la Seccion
  @l{elisp.html#Debugging<>Depurando Programas Lisp} en @e{El Manual de
  Referencia de GNU Emacs Lisp}. En este capítulo, voy a explicar un breve ejemplo
  de cada uno de ellos.

** @c{debug}

   Supón que has escrito una definición de función que pretende devolver la suma
   de los números números desde 1 a un número dado. (Esta es la función
   @c{triangulo} discutida anteriormente. Para mas información, consulta la
   Seccion @l{#Ejemplo con contador decreciente}.)

   Sin embargo, tu definición de función tiene un error. Has escrito
   @c{1=} en lugar de @c{1-}. Aquí está la definición rota:

   ..src > elisp
     (defun triangulo-defectuoso (numero)
       "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO."
       (let ((total 0))
         (while (> numero 0)
           (setq total (+ total numero))
           (setq numero (1= numero)))     ; Error aquí.
         total))
   < src..

   Si estas leyendo esto en Emacs, puedes evaluar la definición de la manera
   habitual. Veras aparecer @c{triangulo-defectuoso} en el área de eco.

   Ahora evalúa la función @c{triangulo-defectuoso} con un argumento de 4:

   ..src > elisp
     (triangulo-defectuoso 4)
   < src..

   En un GNU Emacs reciente, se creará e ingresaras a un búfer
   @f{*Backtrace*} que dice:

   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--Lisp error: (void-function 1=)
       (1= numero)
       (setq numero (1= numero))
       (while (> numero 0)
          (setq total (+ total numero))
          (setq numero (1= numero)))
       (let ((total 0))
          (while (> numero 0)
            (setq total (+ total numero))
            (setq numero (1= numero)))
         total)
       triangulo-defectuoso(4)
       eval((triangulo-defectuoso 4) nil)
       elisp--eval-last-sexp(nil)
       eval-last-sexp(nil)
       call-interactively(eval-last-sexp)
     ---------- Buffer: *Backtrace* ----------
   < example..

   (He reformateado ligeramente este ejemplo; el depurador no corta las lineas
   largas. Como de costumbre, se puede salir del depurador escribiendo @k{q} en el
   buffer @f{*Backtrace*}.)

   En la práctica, para un error tan simple como este, la línea de ‘error
   Lisp’ dira lo que se necesita saber para corregir la definición. La
   función @c{1=} está ‘vacía’.

   Sin embargo, suponiendo que no estas seguro de lo que está pasando, puedes
   leer el registro completo.

   En este caso, necesitas ejecutar una versión reciente de GNU Emacs, que
   inicie automáticamente el depurador que te coloca en el búfer
   @f{*Backtrace*}; o bien, necesitas iniciar manualmente el depurador como
   se describe a continuacion.

   Lee el búfer @f{*Backtrace*} de abajo hacia arriba; emacs te informa la causa
   que provoco el error. Emacs hizo una llamada interactiva a @k{C-x C-e}
   @%c(eval-last-sexp), que produjo la evaluación de la expresión
   @c{triangulo-defectuoso}. Cada línea anterior cuenta lo que el intérprete
   Lisp evaluó a continuacion.

   La tercera línea iniciando en la parte superior del búfer es

   ..src > elisp
     (setq number (1= number))
   < src..

   Emacs intentó evaluar esta expresión; para ello, intentó evaluar
   la expresión interna mostrada en la segunda línea desde arriba:

   ..src > elisp
     (1= number)
   < src..

   Aquí es donde ocurrio el error; como dice en la línea superior:

   ..example >
     Debugger entered--Lisp error: (void-function 1=)
   < example..

   Puedes corregir el error, reevalúar la definición de función, y a continuacion
   ejecutar de nuevo la prueba.

** @c{debug-on-entry}

   Un GNU Emacs actual inicia el depurador automáticamente cuando la función
   tiene un error.

   Por cierto, se puede iniciar el depurador manualmente para todas las
   versiones de Emacs; la ventaja es que el depurador se ejecuta incluso si
   no hay ningun error en el código. Algunas veces, ¡tu código estará libre
   de errores!

   Puedes entrar en el depurador llamando a la función @c{debug-on-entry}.

   Presiona:

   ..example >
     M-x debug-on-entry RET triangulo-defectuoso RET
   < example..

   Ahora, evalúa lo siguiente:

   ..src > elisp
     (triangulo-defectuoso 5)
   < src..

   Todas las versiones de Emacs crearán un búfer @f{*Backtrace*} e informaran
   que estas iniciando la evaluacion de la función @c{triangulo-defectuoso}:

   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--entering a function:
     * triangulo-defectuoso(5)
       eval((triangulo-defectuoso 5))
       eval-last-sexp-1(nil)
       eval-last-sexp(nil)
       call-interactively(eval-last-sexp)
     ---------- Buffer: *Backtrace* ----------
   < example..

   Ya en el búfer @f{*Backtrace*}, pulsa @k{d}. Emacs evaluará la primer
   expresión en @c{triangulo-defectuoso}; el búfer tendra este aspecto:

   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--beginning evaluation of function call form:
     * (let ((total 0)) (while (> numero 0) (setq total ...)
             (setq numero ...)) total)
     * triangulo-defectuoso(5)
       eval((triangulo-defectuoso 5))
       eval-last-sexp-1(nil)
       eval-last-sexp(nil)
       call-interactively(eval-last-sexp)
     ---------- Buffer: *Backtrace* ----------
   < example..

   Ahora, presiona @k{d} de nuevo, ocho veces, lentamente. Cada vez que
   presionas @k{d} Emacs evaluará otra expresión en la definición de función.

   Eventualmente, el búfer se vera asi:

   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--beginning evaluation of function call form:
     * (setq numero (1= numero))
     * (while (> numero 0) (setq total (+ total numero))
             (setq numero (1= numero)))
     * (let ((total 0)) (while (> numero 0) (setq total ...)
             (setq numero ...)) total)
     * triangulo-defectuoso(5)
       eval((triangulo-defectuoso 5))
       eval-last-sexp-1(nil)
       eval-last-sexp(nil)
       call-interactively(eval-last-sexp)
     ---------- Buffer: *Backtrace* ----------
   < example..

   Finalmente, después de escribir @k{d} dos veces más, Emacs llegara al error
   y las dos líneas superiores del buffer @f{*Backtrace*} se veran así:

   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--Lisp error: (void-function 1=)
     * (1= numero)
     …
     ---------- Buffer: *Backtrace* ----------
   < example..

   Presionando @k{d}, fuiste capaz de pasear a través de la función.

   Se puede salir de un buffer @f{*Backtrace*} pulsando @k{q}; esto cierra
   el registro, pero no cancela @c{debug-on-entry}.

   Para cancelar el efecto de @c{debug-on-entry}, llama a
   @c{cancel-debug-on-entry} y el nombre de la función, asi:

   ..example >
     M-x cancel-debug-on-entry RET triangulo-defectuoso RET
   < example..

   (Si está leyendo esto en Emacs, cancela @c{debug-on-entry} ahora.)

** @c{debug-on-quit} y @c{(debug)}

   Ademas de configurar @c{debug-on-error} o llamar a @c{debug-on-entry}, hay
   otras dos maneras de iniciar @c{debug}.

   Puedes iniciar @c{debug} cada vez que presiones @k{C-g} @%c(keyboard-quit)
   configurando la variable @c{debug-on-quit} en @c{t}. Esto es útil para
   depurar bucles infinitos.

   O bien, puedes insertar un línea que diga @c{(debug)} dentro de tu código
   donde quieras que inicie el depurador, así:

   ..src > elisp
     (defun triangulo-defectuoso (numero)
       "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO."
       (let ((total 0))
         (while (> numero 0)
           (setq total (+ total numero))
           (debug)                         ; Empieza el depurador.
           (setq number (1= number)))      ; Error aquí.
         total))
   < src..

   La función @c{debug} se describe en detalle en @l{elisp.html#Debugger<>El
   Depurador Lisp} en @e{El Manual de Referencia GNU Emacs Lisp}.

** El depurador de nivel de fuente @c{edebug}

   Edebug es un depurador a nivel de fuente. Edebug normalmente muestra
   el codigo fuente que estás depurando, con una flecha a la
   izquierda que muestra que línea se está ejecutando actualmente.

   Es posible desplazarse a través de la ejecución de una función, línea a línea, o
   ejecutarla rápidamente hasta alcanzar un @:{punto de ruptura} donde la
   ejecución se detenga.

   Edebug se describe en la Seccion @l{elisp.html#Edebug<>Edebug} en @e{El
   Manual de Referencia de GNU Emacs Lisp}.

   Aquí hay una función con errores de @c{triangulo-recursivo}. Consulta la
   Sección @l{#Recursión en lugar de un contador}, para una revisión de la misma.

   ..src > elisp
     (defun triangulo-recursivo-defectuoso (numero)
       "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO.
     Usa recursion."
       (if (= numero 1)
           1
         (+ numero
            (triangulo-recursivo-defectuoso
             (1= numero)))))                 ; Error aquí.
   < src..

   Normalmente, se instalaría esta definición colocando el cursor después
   del parentesis que cierra la funcion y presionando @k{C-x C-e}
   @%c(eval-last-sexp) o bien colocando el cursor dentro de la definición y
   escribiendo @k{C-M-x} @%c(eval-defun). (Por defecto, el comando
   @c{eval-defun} solo funciona en modo Emacs Lisp o en el modo
   interactivo de Lisp.)

   Sin embargo, para preparar esta definición de función para Edebug, se debe
   primero @:{instrumentar} el código usando un comando diferente. Se puede
   hacer esto colocando el cursor dentro o justo después de la definición y
   escribir

   ..example >
     M-x edebug-defun RET
   < example..

   Esto hará que Emacs cargue Edebug automáticamente si aun no está
   cargado, y que intrumente correctamente la función.

   Después de instrumentar la función, coloca el cursor después de la siguiente
   expresión y escribe @k{C-x C-e} @%c(eval-last-sexp):

   ..src > elisp
     (triangulo-recursivo-defectuoso 3)
   < src..

   Saltaras de nuevo al codigo fuente de @c{triangulo-recursivo-defectuoso} y
   el cursor estara al principio de la linea @c{if} de la
   función. Ademas, verás la punta de una flecha a la izquierda de esa
   línea donde se está ejecutando la función. (En los siguientes ejemplos, se
   muestra la flecha con @'{=>}; en un sistema de ventanas, se puede ver la
   flecha como un triángulo sólido @%'(▸) en el @'(borde) de la ventana.)

   ..example >
     =>★(if (= numero 1)
   < example..

   En el ejemplo, la posición del punto se muestra con una estrella, @'{★}.

   Si ahora presionas @k{SPC}, el punto se moverá a la siguiente expresión
   a ser ejecutada; la línea se vera asi:

   ..example >
     =>(if ★(= numero 1)
   < example..

   Al continuar presionando @k{SPC}, el punto se moverá de una
   expresión a otra. Al mismo tiempo, siempre que una expresión
   devuelva un valor, este valor se mostrara en el área de eco. Por ejemplo,
   después de mover el punto pasado @c{numero}, se verá lo siguiente:

   ..example >
     Result: 3 (#o3, #x3, ?\C-c)
   < example..

   Esto significa que el valor de @c{numero} es 3, que es tres en octal, tres
   en hexadecimal, y ‘control-c’ en @A{ASCII} (la tercer letra del alfabeto, en
   caso de que se necesite conocer esta información).

   Puedes continuar moviéndote a través del código hasta que llegues a la
   línea con el error. Antes de la evaluación, esta línea se ve asi:

   ..example >
     =>        ★(1= numero)))))               ; Error aquí.
   < example..

   Cuando presiones @k{SPC} de nuevo, aparecera un mensaje de error que dice:

   ..example >
     Symbol's function definition is void: 1=
   < example..

   Este es el error.

   Presiona @k{q} para salir de Edebug.

   Para eliminar la instrumentación de una definición de función,
   simplemente se reevalúa con un comando que no la instrumente. Por ejemplo,
   se podría colocar el cursor después del parentesis que cierra la definición
   y presionar @k{C-x C-e}.

   Edebug hace mucho mas que caminar atravez de una función. Se puede configurar
   para que corra por si solo, deteniendose solo en un error o en puntos
   específicos, se puede hacer que muestre los valores cambiantes de varias
   expresiones; encontrar cuantas veces se llama a una función, y mucho más.

   Edebug se describe en @l{elisp.html#Edebug<>Edebug} en @e{El Manual de
   Referencia de GNU Emacs Lisp}.

** Ejercicios de depuración

   - Instala la función @c{count-words-example} y luego haz que entre en el
     depurador cuando se llame. Ejecuta el comando en una región que contenga
     dos palabras. Tendras que presionar @k{d} un número considerable de
     veces. En tu sistema, ¿se llama a un ‘hook’ cuando termina el comando?. (Para
     mas información sobre los hooks, consulta la Seccion @l{elisp.html#Command
     Overview<>Command Overview} en @e{El Manual de Referencia de GNU Emacs Lisp}.)

   - Copia @c{count-words-example} dentro del búfer @f{*scratch*}, instrumenta
     la función para Edebug, y navega a través de su ejecución. La función
     no necesita tener un error, aunque se puede introducir uno si se
     desea. Si la función carece de errores, el recorrido se completa sin
     problemas.

   - Mientras se ejecuta Edebug, presiona @k{?} para ver una lista de todos
     los comandos Edebug. (El @c{global-edebug-prefix} normalmente es @k{C-x
     X}, es decir: @k{CTRL-x} seguido por una tecla mayúscula @k{X}; utuliza
     este prefijo para realizar comandos fuera del búfer de depuración
     Edebug.)

   - En el búfer de depuración Edebug, usa el comando @k{p}
     @%c(edebug-bounce-point) para ver en que parte de la region esta trabajando
     @c{count-words-example}.

   - Mueve el punto a algún sitio mas abajo en la función y luego utiliza el
     comando @k{h} @%c(edebug-goto-here) para saltar a esa localización.

   - Usa el comando @k{t} @%c(edebug-trace-mode) para hacer que Edebug
     recorra la funcion por si mismo; usa una @k{T} mayúscula para
     @c{edebug-Trace-fast-mode}.

   - Asigna un punto de ruptura, luego ejecuta Edebug en modo Trace hasta
     que alcance el punto de parada.

* Conclusión

  Hemos llegado al fin de esta Introducción. Has aprendido lo suficiente sobre
  programación en Emacs Lisp para establecer valores, escribir ficheros
  @f{.emacs} para tí y tus amigos, y escribir personalizaciones y
  extensiones simples para Emacs.

  Este es un lugar para parar. O, si lo deseas, seguir adelante, y
  aprender por ti mismo.

  Se han aprendido algunos de los aspectos basicos de la programación. Pero solo
  algunos. Todavía hay muchos conceptos que son fáciles de usar y que no hemos
  tocado.

  Otra ruta a seguir ahora mismo se encuentra entre el codigo fuente de Emacs y
  en @e{El Manual de Referencia de GNU Emacs}.

  El codigo de Emacs Lisp es una aventura. Cuando lo lees y te encuentras con una
  función o expresión que no es familiar, necesitas imaginar o averiguar lo
  qué hace.

  Consulta el Manual de Referencia. Es una descripcion completa y bastante fácil
  de leer de Emacs Lisp. Está escrito no solo para expertos, sino tambien para
  personas que saben lo que tu sabes. (El @e{Manual de Referencia} viene con la
  distribución de GNU Emacs. Al igual que esta introducción, viene como un
  fichero fuente de Texinfo, para que puedas leerlo en linea y como una
  composicion tipografica, o como un libro impreso.)

  Puedes acudir a la ayuda en linea que es parte de GNU Emacs: la documentación
  en linea para todas las funciones y variables, y @c{find-tag}, el programa que
  te lleva al codigo fuente.

  He aquí un ejemplo de cómo exploro las fuentes. Por su nombre, @f{simple.el}
  es el fichero que mire primero, hace mucho tiempo. Ocurre que algunas de las
  funciones en @f{simple.el} son complicadas, o al menos parecen complicadas a
  primera vista. La función @c{open-line}, por ejemplo, parece complicada.

  Es posible que desees explorar esta función lentamente, como
  hicimos con la función @c{forward-sentence}. (Consulta la Seccion @l{#La función
  @c{forward-sentence}}.) O tal vez quieras saltarte esta función y mirar
  otra, como @c{split-line}. No es necesario leer todas las funciones. Segun
  @c{contar-palabras-en-definicion}, la función @c{split-line} contiene 102
  palabras y símbolos.

  Aunque es pequeña, @c{split-line} contiene expresiones que no hemos
  estudiado: @c{skip-chars-forward}, @c{indent-to}, @c{current-column} e
  @c{insert-and-inherit}.

  Considera la función @c{skip-chars-forward}. (Forma parte de la definición de
  función para @c{back-to-indentation}, que se muestra en la Seccion de
  @l(#Repaso: Cómo escribir definiciones de funcion<>Repaso).)

  En GNU Emacs, puedes encontrar más informacion acerca de @c{skip-chars-forward}
  presionando @k{C-h f} @%c(describe-function) y el nombre de la función. Esto
  te proporciana la documentación de la función.

  Puedes ser capaz de adivinar lo que hace una función con un buen nombre como
  @c{indent-to}; o en su defecto puedes buscar su descripcion. Por cierto, la
  función @c{describe-function} en sí misma está en @f{help.el}; es una de esas
  funciones largas, pero descifrables. ¡Puedes buscar @c{describe-function}
  usando el comando @k{C-h f}!

  En este caso, dado que el código es Lisp, el búfer @f{*Help*} contiene
  el nombre de la librería que contiene el origen de la función. Puedes
  colocar el punto sobre el nombre de la librería y pulsar la tecla RET,
  que en está situación está asociada a @c{help-follow}, y ser llevado
  directamente al codigo fuente, de la misma manera que con @k{M-.} @%c(find-tag).

  La definición para @c{describe-function} ilustra como personalizar las
  expresiones @c{interactive} sin usar los códigos de caracter estándar y
  muestra como crear un búfer temporal.

  (La función @c{indent-to} esta escrita en C en lugar de Emacs Lisp; es una
  función ‘nativa’. Cuando se configura correctamente, @c{help-follow} te lleva
  a su fuente al igual que @c{find-tag}.)

  Puedes mirar la fuente de una función usando @c{find-tag}, que está
  vinculada a @k{M-.}. Finalmente, puedes encontrar lo que el Manual de
  Referencia tiene que decir visitando el manual en Info, e ingresando
  @k{i} @%c(Info-index) y el nombre de la función, o buscando la función en el
  índice de una copia impresa del manual.

  Del mismo modo, puedes encontrar que significa mediante @c{insert-and-inherit}.

  Otros ficheros fuente interesantes son @f{paragraphs.el}, @f{loaddefs.el} y
  @f{loadup.el}. El fichero @f{paragraphs.el} incluye funciones cortas y faciles
  de entender, asi como funciones mas extensas. El fichero @f{loaddefs.el}
  contiene muchos autoloads estándar y muchos mapas de teclado. Nunca he visto
  todo; solo algunas partes. @f{loadup.el} es el fichero que carga las partes
  estándar de Emacs; te dice mucho sobre como se construye Emacs. (Para mas
  informacion, consulta la Seccion @l{elisp.html#Building Emacs<>Construyendo
  Emacs} en @e{El Manual de Referencia de GNU Emacs Lisp}.)

  Como he dicho, has aprendido algunos detalles; sin embargo, y muy
  importante, apenas hemos tocado aspectos importantes de la programación; no se ha
  dicho nada acerca de como clasificar la información, excepto usar la
  función predefinida @c{sort}; no he dicho nada acerca de cómo almacenar
  la información, excepto usar variables y listas; no he dicho nada
  acerca de como escribir programas que escriben programas. Esto son temas
  para otro tipo de libro, y otro tipo de aprendizaje.

  Lo que has hecho es aprender lo suficiente para hacer mucho trabajo práctico
  con GNU Emacs. Lo que has hecho es comenzar. Este es el final de un comienzo.

* Apéndice A: La función @c{el-el}

  Algunas veces cuando se se escribe texto, se duplican palabras––como con “se
  se” cerca del principio de esta frase. En mi caso, encuentro que lo más
  frecuente, es duplicar “el”; por lo tanto, llamo a la función @c(el-el) para
  detectar las palabras duplicadas.

  Como primer paso, se puede utilizar la siguiente expresion regular
  para buscar duplicados:

  ..example >
    \\(\\w+[ \t\n]+\\)\\1
  < example..

  Esta regexp coincide con uno o más caracteres que constituyen palabras seguidas
  por uno o más espacios, tabuladores, o líneas nuevas. Sin embargo, no
  detecta palabras duplicadas en líneas diferentes, ya que el final de la
  la primer palabra, el final de la línea, es diferente del final de la
  segunda palabra, un espacio. (Para más información acerca de expresiones
  regulares, mira el Capitulo 12 @l{#Búsqueda de Expresiones Regulares}, asi
  como la Seccion @l{emacs.html#Regexps<>Sintaxis de Expresiones Regulares} en @e{El Manual
  de GNU Emacs}, y la Seccion @l{elisp.html#Regular Expressions<>Expresiones Regulares} en @e{El Manual de
  Referencia de GNU Emacs Lisp}.)

  Puedes intentar buscar solo duplicados para caracteres consecutivos que constituyen
  palabras, pero eso no funciona, ya que el patron detecta dobles como las dos
  ocurrencias de ‘al’ en ‘igual al’.

  Otra posible regexp busca caracteres que constituyen palabras, seguido por
  caracteres que no constituyen palabras, reduplicadas. Aquí, @c{\\w+}
  coincide con uno o más caracteres que forman palabras y @c{\\W*} con
  cero o más caracteres que no forman palabras.

  ..example >
    \\(\\(\\w+\\)\\W*\\)\\1
  < example..

  De nuevo, no es útil.

  Aquí está el patrón que uso. No es perfecto, pero es lo suficientemente
  bueno. @c{\\b} coincide con la cadena vacía siempre y cuando este al
  principio o al final de una palabra; @c{[^@@ \n\t]+} coincide con una o más
  ocurrencias de cualquier caracter que @e{no} son sea el signo @@, un espacio, nueva
  línea, o tabulador.

  ..example >
    \\b\\([^@ \n\t]+\\)[ \n\t]+\\1\\b
  < example..

  Uno puede escribir expresiones más complicadas, pero encontre que esta
  expresión es lo suficientemente buena, así que la uso.

  Aquí está la función @c{el-el}, tal y como la incluyo en mi fichero
  @f{.emacs}, junto con un practico atajo global:

  ..src > elisp
    (defun el-el ()
      "Busca hacia adelante una palabra duplicada."
      (interactive)
      (message "Buscando palabras duplicadas ...")
      (push-mark)
      ;; Este regexp no es perfecto
      ;; pero a pesar de todo, es bastante bueno:
      (if (re-search-forward
           "\\b\\([^@ \n\t]+\\)[ \n\t]+\\1\\b" nil 'move)
          (message "Palabra duplicada encontrada.")
        (message "Fin de búfer")))

    ;; Asocia ‘el-el’ a  C-c \
    (global-set-key "\C-c\\" 'el-el)
  < src..

  Aquí está el texto de prueba:

  ..example >
    uno dos dos tres cuatro cinco
    cinco seis siete
  < example..

  Puedes sustituir la regexp con las mostradas anteriormente y probar cada una
  de ellas en esta lista.

* Apéndice B: Manejando el anillo de la muerte

  El anillo de la muerte es una lista que se transforma en un anillo por el
  funcionamiento de la función @c{current-kill}. Los comandos @c{yank} y
  @c{yank-pop} usan la función @c{current-kill}.

  Este apéndice describe la función @c{current-kill} asi como los comandos
  @c{yank} y @c{yank-pop}, pero primero, examinemos el funcionamiento del anillo
  de la muerte.

  El anillo de la muerte tiene una longitud maxima predeterminada de sesenta
  elementos; hacer una explicación del porque de este número quedaría demasiado
  extenso. En su lugar, pensemos qué ocurre si se establece en cuatro. Por favor,
  evalúa lo siguiente:

  ..src > elisp
    (setq old-kill-ring-max kill-ring-max)
    (setq kill-ring-max 4)
  < src..

  Despues, por favor copia cada línea del siguiente ejemplo indentado
  dentro del anillo de la muerte. Se puede cortar cada línea
  con @k{C-k} o marcarla y copiarla con @k{M-w}.

  (En un búfer de solo lectura, como el búfer @f{*info*}, el comando kill,
  @k{C-k} @%c(kill-line), no eliminará el texto, solamente lo copiara al anillo
  de la muerte. Sin embargo, el ordenador puede emitir un beep. Alternativamente,
  para evitarlo, se puede copiar la región de cada línea con el comando
  @k{M-w} @%c(kill-ring-save). Debes marcar cada línea para que este comando
  tenga exito, pero no importa en que extremo se coloque el punto o la marca.)

  Por favor, invoca las llamadas en orden, de modo que los cinco elementos
  intenten llenar el anillo de la muerte.

  ..example >
    primero un poco de texto
    segundo fragmento de texto
    tercer línea
    cuarta línea de texto
    quinta parte del texto
  < example..

  Luego encuentra el valor de @c{kill-ring} evaluando

  ..example >
    kill-ring
  < example..

  que es:

  ..src > elisp
    ("quinta parte del texto" "cuarta línea de texto"
     "tercer línea" "segundo fragmento de texto")
  < src..

  El primer elemento, @'{primero un poco de texto}, se descarto.

  Para volver al valor anterior del tamaño del kill ring, evalúa:

  ..src > elisp
    (setq kill-ring-max old-kill-ring-max)
  < src..

** La función @c{current-kill}

   La función @c{current-kill} cambia el elemento en el anillo de la muerte al
   que apunta @c{kill-ring-yank-pointer}. (Ademas, la función @c{kill-new}
   establece @c{kill-ring-yank-pointer} para que apunte al último elemento del
   anillo de la muerte. La función @c{kill-new} se utiliza directamente o
   indirectamente en las funciones @c{kill-append}, @c{copy-region-as-kill},
   @c{kill-ring-save}, @c{kill-line}, y @c{kill-region}.)

   La función @c{current-kill} es usada por @c{yank} y por
   @c{yank-pop}. Aquí está el código para @c{current-kill}:

   ..src > elisp
     (defun current-kill (n &optional do-not-move)
       "Rota el punto de pegado por N lugares, y entonces devuelve el corte.
     Si N es cero, se establece ‘interprogram-paste-function’, y si se llama
     devuelve una cadena, entonces esa cadena se añade al frente del
     anillo de la muerte y devuelve el último corte.
     Si el argumento opcional DO-NOT-MOVE no es nulo, entonces no mueve el
     punto de pegado; solo devuelve el Nth corte hacia adelante.
        (let ((interprogram-paste (and (= n 0)
                                       interprogram-paste-function
                                       (funcall interprogram-paste-function)))))
         (if interprogram-paste
             (progn
               ;; Deshabilita la función de corte interprograma cuando se añade
               ;; el nuevo texto al anillo de la muerte, para que Emacs no intente
               ;; apropiarse de la selección con texto idéntico.
               (let ((interprogram-cut-function nil))
                 (kill-new interprogram-paste))
               interprogram-paste)
           (or kill-ring (error "El anillo de la muerte esta vacio"))
           (let ((ARGth-kill-element
                  (nthcdr (mod (- n (length kill-ring-yank-pointer))
                               (length kill-ring))
                          kill-ring)))
             (or do-not-move
                 (setq kill-ring-yank-pointer ARGth-kill-element))
             (car ARGth-kill-element)))))
   < src..

   Recuerda también que la función @c{kill-new} asigna
   @c{kill-ring-yank-pointer} al último elemento del anillo de la muerte,
   lo que significa que todas las funciones que la llaman establecen
   el valor de forma indirecta: @c{kill-append}, @c{copy-region-as-kill},
   @c{kill-ring-save}, @c{kill-line} y @c{kill-region}.

   Aquí está la línea en @c{kill-new}, que se explica en la Seccion
   @l{#La función @c{kill-new}}.

   ..src > elisp
     (setq kill-ring-yank-pointer kill-ring)
   < src..

   La función @c{current-kill} parece compleja, pero como de costumbre, se puede
   entender desmontandola pieza por pieza. Primero mírala en forma de esqueleto:

   ..src > elisp
     (defun current-kill (n &optional do-not-move)
       "Rota el punto de pegado por N lugares, y entonces devuelve el corte.
       (let varlist
         cuerpo…)
   < src..

   Esta función toma dos argumentos, uno de los cuales es opcional. Tiene una cadena de
   documentación. @e{No} es una función interactiva.

   El cuerpo de la definición de función es una expresión @c{let}, que a su vez
   tiene un cuerpo asi como una @c{varlist}.

   La expresión @c{let} declara una variable que solo será utilizable dentro de
   los limites de esta función. Esta variable se llama @c{interprogram-paste} y
   es para copiar a otro programa. No es para copiar dentro de esta instancia de
   GNU Emacs. La mayoría de los sistemas de ventanas proveen una facilidad para
   el pegado interprograma. Tristemente, esta facilidad normalmente solo provee
   el último elemento. La mayoría de los sistemas de ventanas no han adoptado un
   anillo de muchas posibilidades, a pesar de que Emacs lo ha proporcionado
   durante décadas.

   La expresión @c{if} tiene dos partes, una si existe
   @c{interprogram-paste} y otra si no.

   Consideremos la parte ‘si no’ o la parte-else de la función
   @c{current-kill}. (La parte-else utiliza la función @c{kill-new}, que ya
   hemos descrito. Consulta la Seccion @l{#La función @c{kill-new}}.)

   ..src > elisp
     (or kill-ring (error "El anillo de la muerte esta vacio"))
     (let ((ARGth-kill-element
            (nthcdr (mod (- n (length kill-ring-yank-pointer))
                         (length kill-ring))
                    kill-ring)))
       (or do-not-move
           (setq kill-ring-yank-pointer ARGth-kill-element))
       (car ARGth-kill-element))
   < src..

   El código primero comprueba si el anillo de la muerte tiene
   contenido; de lo contrario, señala un error.

   Observa que la expresión @c{or} es muy similar en longitud a una prueba con un
   @c{if}:

   ..src > elisp
     (if (zerop (length kill-ring))            ; parte-if
         (error "El Kill ring está vacío"))    ; parte-then
       ;; No hay parte-else
   < src..

   Si no hay nada en el anillo de la muerte, su tamaño debe
   ser cero y un mensaje de error se envía al usuario: @'{El kill ring está
   vacío}. La función @c{current-kill} usa una expresión @c{or} que es mas
   simple. Pero una expresión @c{if} nos recuerda lo que ocurre.

   Esta expresión @c{if} usa la función @c{zerop} que devuelve verdadero si el
   valor que esta probando es cero. Cuando la prueba @c{zerop} es verdadera, se
   evalúa la parte-then del @c{if}. La parte-then es una lista que comienza con
   la función @c{error}, que es una función similar a la función @c{message}
   (Consulta la Sección @l{#La Función @c{message}}) en el sentido que imprime un
   mensaje de una línea en el área de eco. Sin embargo, además de imprimir un
   mensaje, @c{error} también detiene la evaluacion de la funcion dentro de la
   cual esta embebida. Esto significa que el resto de la función no se
   evaluara si la longitud del anillo de la muerte es cero.

   Entonces la función @c{current-kill} selecciona el elemento a
   devolver. La selección depende del número de lugares en los que @c{current-kill}
   rota y donde apunta @c{kill-ring-yank-pointer}.

   A continuacion, el argumento opcional @c{do-not-move} es verdadero o el
   valor actual de @c{kill-ring-yank-pointer} se establece para apuntar a la
   lista. Finalmente, otra expresión devuelve el primer elemento de la lista
   incluso si el argumento @c{do-not-move} es verdadero.

   En mi opinión, es ligeramente engañoso, al menos para humanos, usar el
   término ‘error’ como el nombre de la función @c{error}. Un término mejor
   sería ‘cancelar’. Estrictamente hablando, por supuesto, no se puede apuntar,
   mucho menos rotar un puntero a una lista que no tiene longitud, por lo que
   desde el punto de vista del ordenador, la palabra ‘error’ es correcta. Pero
   un humano espera intentar este tipo de cosas, aunque solo sea para averiguar
   si el anillo de la muerte esté lleno o vacío. Esto es un acto de exploración.

   Desde el punto de vista humano, el acto de exploración y descubrimiento no es
   necesariamente un error, y por lo tanto, no debe etiquetarse como tal, ni
   siquiera en las entrañas de un ordenador. Tal como estan las cosas, el codigo
   de Emacs implica que un humano que está actuando virtuosamente, explorando su
   entorno, está cometiendo un error. Esto está mal. Incluso aunque el ordenador
   tome los mismos pasos que cuando hay un ‘error’, un término como ‘cancelar’
   tendría una connotación mas clara.

   Entre otras acciones, la parte-else de la expresión @c{if} establece el valor
   de @c{kill-ring-yank-pointer} a @c{ARGth-kill-element} cuando el
   anillo de la muerte tiene alguna cosa dentro y el valor de
   @c{do-not-move} es @c{nil}.

   El código se ve asi:

   ..src > elisp
     (nthcdr (mod (- n (length kill-ring-yank-pointer))
                  (length kill-ring))
             kill-ring)))
   < src..

   Esto necesita algún examen. A menos que no se suponga mover el puntero, la
   función @c{current-kill} cambia a donde apunta @c{kill-ring-yank-pointer}.
   Esto es lo que hace la expresión @c{(setq kill-ring-yank-pointer
   ARGth-kill-element)}. También, claramente, @c{ARGth-kill-element}
   está siendo asignado para ser igual a algún @c{cdr} del anillo de la
   muerte, usando la función @c{nthcdr} que se describio en
   una sección anterior. (Consulta la Seccion @l{#@c(copy-region-as-kill)}.)  ¿Cómo
   hace esto?

   Como vimos antes (en la Sección @l{#@c(nthcdr)}), la función @c{nthcdr}
   funciona tomando repetidamente el @c{cdr} de una lista––toma el
   @c{cdr}, del @c{cdr}, del @c{cdr} …

   Las dos expresiones siguientes producen el mismo resultado:

   ..src > elisp
     (setq kill-ring-yank-pointer (cdr kill-ring))

     (setq kill-ring-yank-pointer (nthcdr 1 kill-ring))
   < src..

   Sin embargo, la expresión @c{nthcdr} es más complicada. Utiliza la función
   @c{mod} para determinar que @c{cdr} seleccionar.

   (Recuerda mirar primero las funciones internas, de hecho, tendremos
   que ir dentro del @c{mod}.)

   La función @c{mod} devuelve el valor de su primer argumento módulo el
   segundo; es decir, devuelve el resto después de dividir el primer
   argumento por el segundo. El valor devuelto tiene el mismo signo que el
   segundo argumento.

   Por lo tanto,

   ..srci > elisp
     > (mod 12 4)
     0  ;; porque no hay resto
     > (mod 13 4)
     1
   < srci..

   En este caso, el primer argumento es con frecuencia mas pequeño que el
   segundo. Eso está bien.

   ..srci > elisp
     > (mod 0 4)
     0
     > (mod 1 4)
     1
   < srci..

   Podemos adivinar lo que hace la función @c{-}. Es como @c{+} pero
   resta en lugar de sumar; la función @c{-} sustrae su segundo argumento
   del primero. Ademas, ya sabemos lo que hace la función @c{length}
   (Ver la Sección @l{#Descubrir la longitud de una lista: @c{length}}).
   Devuelve la longitud de una lista.

   Y @c{n} es el nombre del argumento requerido para la función
   @c{current-kill}.

   Así que cuando el primer argumento de @c{nthcdr} es cero, la expresión
   @c{nthcdr} devuelve la lista entera, como puedes ver evaluando lo
   siguiente:

   ..src > elisp
     ;; kill-ring-yank-pointer y kill-ring tienen una longitud de cuatro
     ;; and (mod (- 0 4) 4) ⇒ 0
     (nthcdr (mod (- 0 4) 4)
             '("cuarta línea de texto"
               "tercer línea"
               "segundo fragmento de texto"
               "primero un poco de texto"))
   < src..

   Cuando el primer argumento para la función @c{current-kill} es uno, la
   expresión @c{nthcdr} devuelve la lista sin su primer elemento.

   ..src > elisp
     (nthcdr (mod (- 1 4) 4)
             '("cuarta línea de texto"
               "tercer línea"
               "segundo fragmento de texto"
               "primero un poco de texto"))
   < src..

   Por cierto, tanto @c{kill-ring} y @c{kill-ring-yank-pointer} son
   @:{variables globales}. Esto significa que cualquier expresión en Emacs
   Lisp puede acceder a ellas. No son como las variables locales
   establecidas por @c{let} o como los símbolos en una lista de argumentos. Solo
   se puede acceder a las variables locales dentro del @c{let} que las define
   o la función que las especifica en una lista de argumentos (y dentro de las
   expresiones llamadas por estas).

** @c{yank}

   Después de aprender sobre @c{current-kill}, el código para la función
   @c{yank} es casi fácil de entender.

   La función @c{yank} no utiliza directamente la variable @c{kill-ring-yank-pointer}.
   Llama a @c{insert-for-yank} que llama a @c{current-kill}
   que establece la variable @c{kill-ring-yank-pointer}.

   El código se ve asi:

   ..src > elisp
     (defun yank (&optional arg)
       "Reinserta (\"pega\") el último fragmento del texto cortado.
     Más concretamente, vuelve a insertar el texto cortado o pegado más reciente.
     Coloca el punto al final, y asigna la marca al principio.
     Con solo \\[universal-argument] como argumento, realiza lo mismo pero coloca el
     punto al principio (y la marca al final). Con el argumento N, reinserta
     el N fragmento más recientemente cortado.

     Cuando este comando inserta texto dentro del búfer, respeta
     a ‘yank-excluded-properties’ y ‘yank-handler’ como describe
     la cadena de documentación de ‘insert-for-yank-1’, que ve.

     Ver también el comando \\[yank-pop]."
       (interactive "*P")
       (setq yank-window-start (window-start))
       ;; Si no llegamos hasta el final, hace que last-command
       ;; indique esto para el siguiente comando.
       (setq this-command t)
       (push-mark (point))
       (insert-for-yank (current-kill (cond
                                       ((listp arg) 0)
                                       ((eq arg '-) -2)
                                       (t (1- arg)))))
       (if (consp arg)
           ;; Esto es como exchange-point-and-mark,
           ;;     pero no activa la marca.
           ;; Es mas limpio para evitar la activación, aunque el bucle de
           ;; comandos desactivaría la marca porque insertamos texto.
           (goto-char (prog1 (mark t)
                        (set-marker (mark-marker) (point) (current-buffer)))))
       ;; Si llegamos hasta el final, hace que this-command lo indique.
       (if (eq this-command t)
           (setq this-command 'yank))
       nil)
   < src..

   La expresión clave es @c{insert-for-yank}, que inserta la cadena devuelta
   por @c{current-kill}, pero elimina algunas propiedades de texto de la misma.

   Sin embargo, antes de llegar a esa expresión, la función establece el valor de
   @c{yank-window-start} a la posición devuelta por la expresión
   @c{(window-start)}, la posición en la que la pantalla comienza actualmente. La
   función @c{yank} también asigna @c{this-command} y añade la marca.

   Después de pegar el elemento apropiado, si el argumento opcional es un
   @c{cons} en vez de un número o nada, coloca el punto al principio del
   texto pegado y la marca al final.

   (La función @c{prog1} es como @c{progn} pero devuelve el valor de su primer
   argumento en vez del valor de su último argumento. Su primer argumento
   fuerza devolver la marca del búfer como un entero. Puede ver la
   documentación para estas funciones colocando el punto sobre ellas en
   este búfer y presionando @k{C-h f} @%c(describe-function) seguido
   por un @k{RET}; la funcion por defecto.)

   La última parte de la función indica que hacer cuando tiene exito.

** @c{yank-pop}

   Después de entender @c{yank} y @c{current-kill}, ya sabes como acercarte
   a la función @c{yank-pop}. Dejando fuera la documentación para ahorrar
   espacio, se ve asi:

   ..src > elisp
     (defun yank-pop (&optional arg)
       "…"
       (interactive "*p")
       (if (not (eq last-command 'yank))
           (error "El comando previo no fué un yank"))
       (setq this-command 'yank)
       (unless arg (setq arg 1))
       (let ((inhibit-read-only t)
             (before (< (point) (mark t))))
         (if before
             (funcall (or yank-undo-function 'delete-region) (point) (mark t))
           (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
         (setq yank-undo-function nil)
         (set-marker (mark-marker) (point) (current-buffer))
         (insert-for-yank (current-kill arg))
         ;; Si es posible, vuelve a colocar el inicio de la ventana en el punto
         ;; en el que se encontraba el comando yank.
         (set-window-start (selected-window) yank-window-start t)
         (if before
             ;; Esto es es como exchange-point-and-mark,
             ;;     pero no activa la marca.
             ;; Es mas limpio para evitar la activación, aunque el bucle de
             ;; comandos desactivaría la marca porque insertamos texto.
             (goto-char (prog1 (mark t)
                          (set-marker (mark-marker)
                                      (point)
                                      (current-buffer))))))
       nil)
   < src..

   La función es interactiva con una pequeña @c{p} para que el argumento del
   prefijo sea procesado y pasado a la función. El comando solo se puede
   utilizar después del yank previo; de lo contrario, se envia un mensaje de
   error. Esta comprobacion utiliza la variable @c{last-command} que se asigna
   por @c{yank} y se discute en otra parte. (Consulta la Seccion
   @l{#@c(copy-region-as-kill)}.

   La cláusula @c{let} asigna la variable @c{before} a verdadero o falso
   dependiendo de si el punto está antes o después de la marca y luego se
   elimina la región entre punto y marca. Esta es la región que acaba de ser
   insertada por el yank previo y es este texto el que será reemplazado.

   @c{funcall} llama a su primer argumento como una función, pasando los
   argumentos restantes. El primer argumento es el que devuelve la expresión
   @c{or}. Los dos argumentos restantes son las posiciones de
   punto y marca establecidas por el comando @c{yank} anterior.

   Hay más, pero esta es la parte más dificil.

** El fichero @f{ring.el}

   De manera interesante, GNU Emacs posee un fichero llamado @f{ring.el} que
   proporciona muchas de las caracteristicas que acabamos de discutir. Sin embargo,
   funciones como @c{kill-ring-yank-pointer} no utilizan esta librería,
   posiblemente porque se escribieron antes.

* Apéndice C: Un grafico con ejes etiquetados

  Los ejes impresos ayudan a comprender un grafico. Para transmitir escalas. En
  un capítulo anterior (Ver Sección @l{#Preparar un grafico}), escribimos código
  para imprimir el cuerpo de un grafico. Aquí escribimos el código para imprimir
  y etiquetar los ejes horizontales y verticales, a lo largo del cuerpo en si.

  Puesto que las inserciones se colocan en un búfer a la derecha y debajo del
  punto, la nueva funcion de impresion de graficos debe imprimir primero el eje
  vertical Y, luego el cuerpo del grafico, y finalmente el eje horizontal
  X. Esta secuencia nos da el contenido de la función:

  1. Codigo de configuracion.

  2. Imprir el eje Y.

  3. Imprir el cuerpo del grafico.

  4. Imprir el eje X.


  He aquí un ejemplo de como se ve un grafico terminado:

  ..example >
    10 -
                  *
                  *  *
                  *  **
                  *  ***
     5 -      *   *******
            * *** *******
            *************
          ***************
     1 - ****************
         |   |    |    |
         1   5   10   15
  < example..

  En este grafico, tanto el eje vertical como el horizontal se etiquetan con
  números. Sin embargo, en algunos graficos, el eje horizontal es el tiempo y
  estaría mejor etiquetarlo con meses, así:

  ..example >
    5 -      *
           * ** *
           *******
         ********** **
    1 - **************
        |    ^      |
      Enero Junio Enero
  < example..

  De hecho, con un poco de reflexion, podemos encontrar fácilmente una variedad
  de esquemas de etiquetado vertical y horizontal. Nuestra tarea podría
  complicarse. Pero las complicaciones generan confusión. En vez de permitir
  esto, es mejor elegir un esquema de etiquetado simple para nuestro primer
  esfuerzo, y modificarlo o reemplazarlo después.

  Estas consideraciones sugieren el siguiente esquema para la función
  @c{imprimir-grafico}:

  ..src > elisp
    (defun imprimir-grafico (lista-de-numeros)
      "documentacion…"
      (let ((altura  …
            …))
        (imprimir-eje-Y altura … )
        (imprimir-cuerpo-grafico lista-de-numeros)
        (imprimir-eje-X … )))
  < src..

  Podemos a su vez trabajar en cada parte de la definición de la función
  @c{imprimir-grafico}.

** La varlist de @c{imprimir-grafico}

   Al escribir la función @c{imprimir-grafico}, la primera tarea es escribir la
   varlist en la expresión @c{let}. (Por el momento dejaremos de lado cualquier
   idea sobre hacer que la función sea interactiva o sobre los contenidos de su
   cadena de documentación.)

   La varlist debe establecer varios valores. Claramente, la parte superior de
   la etiqueta para el eje vertical debe ser al menos la altura del grafico, lo
   que significa que debemos obtener esta información aquí. Ten en cuenta que la función
   @c{imprimir-cuerpo-grafico} también requiere esta información. No hay ninguna
   razón para calcular la altura del grafico en dos lugares diferentes, por lo que
   debemos modificar @c{imprimir-cuerpo-grafico} para aprovechar el cálculo.

   De manera similar, tanto la función para imprimir la etiqueta del eje X y la
   función @c{imprimir-cuerpo-grafico} necesita aprender el valor del ancho de
   cada símbolo. Podemos realizar el cálculo aquí y cambiar la definición de
   @c{imprimir-cuerpo-grafico} que definimos en el capítulo anterior.

   La longitud de la etiqueta para el eje horizontal debe ser al menos igual que
   la del grafico. Sin embargo, esta información solo se usa en la función que
   imprime el eje horizontal, por lo que no es necesario calcularla aqui.

   Estos pensamientos nos llevan directamente a la siguiente forma para la
   varlist en el @c{let} de @c{imprimir-grafico}:

   ..src > elisp
     (let ((altura (apply 'max lista-de-numeros)) ; Primera versión.
           (ancho-del-simbolo (length simbolo-en-blanco)))
   < src..

   Como veremos, esta expresión no es del todo correcta.

** La función @c{imprimir-eje-Y}

   El trabajo de la función @c{imprimir-eje-Y} es imprimir una etiqueta para el
   eje vertical que tenga este aspecto:

   ..example >
     10 -




      5 -



      1 -
   < example..

   La función debe pasarse a la altura del grafico, y luego debe construir e insertar los
   números y marcas apropiados.

   Es suficientemente fácil ver en la figura como deberia ser la etiqueta del
   eje Y; pero decir con palabras, y luego escribir una definición de función
   para hacer el trabajo es otro asunto. No es del todo cierto decir que
   queremos un número y una marca cada cinco líneas: solo hay tres líneas entre
   el @'{1} y el @'{5} (líneas 2, 3 y 4), pero cuatro líneas entre el @'{5} y el
   @'{10} (líneas 6, 7, 8 y 9). Es mejor decir que se quiere un número y una
   marca en la quinta línea desde la parte inferior y en cada línea que sea un
   múltiplo de cinco.

   La siguiente cuestión es que altura debe tener la etiqueta. Supóngamos que la
   altura máxima de la columna mas alta del grafico es siete. Debe la etiqueta
   mas alta en el eje Y ser @'{5 -}, ¿y el grafico sobresalir por encima de la
   etiqueta?, ¿o la etiqueta mas alta ser @'{7 -}, y marcar el pico del grafico?
   ¿o deberia ser @'{10 -}, que es un múltiplo de cinco, y ser mas alta que el
   valor más alto del grafico?

   Se prefiere esta última forma. La mayoría de los graficos se dibujan dentro
   de rectángulos cuyos lados son un número integral de pasos de longitud––5, 10,
   15, y así sucesivamente para una distancia de paso de cinco. Pero tan pronto
   como decidimos usar una altura de escalon para el eje vertical, descubrimos
   que la expresión simple en la varlist para calcular la altura es incorrecta.
   La expresión es @c{(apply 'max lista-de-numeros)}. Esto devuelve la altura
   precisa, no la altura máxima más lo que sea necesario para redondear al
   múltiplo de cinco. Se requiere una expresión más compleja.

   Como es habitual en casos como este, un problema complejo se simplifica
   si se divide en varios problemas mas pequeños.

   Primero, considere el caso cuando el valor superior del grafico es un
   múltiplo integral de cinco––cuando eso es 5, 10, 15, o algún múltiplo de
   cinco. Podemos usar este valor como la altura del eje Y.

   Una manera bastante simple para determinar si un número es múltiplo de cinco
   es dividirlo por cinco y ver si la división devuelve un resto. Si no hay
   ningun resto, el número es un múltiplo de cinco. De este modo, siete dividido
   por cinco tiene un resto de dos, y siete no es un múltiplo integral de
   cinco. Dicho de otra manera, en un lenguaje que recuerde al de un salon de
   clases, cinco se divide en siete una vez y el resto es dos. Sin embargo,
   cinco se divide en diez dos veces y no tiene resto: diez es un múltiplo
   integral de cinco.

*** Viaje lateral: Calcula un resto

    En Lisp, la función para calcular un resto es @c{%}. La función devuelve el
    resto de su primer argumento dividido por su segundo argumento. Da la
    casualidad que @c{%} es una función en Emacs Lisp que no se puede
    descubrir usando @c{apropos}: no se encuentra nada al escribir @k{M-x
    apropos RET resto RET}. La unica forma de conocer la existencia de @c{%} es
    leer sobre ello en un libro como este o en las fuentes de Emacs Lisp.

    Puedes probar la función @c{%} evaluando las dos siguientes expresiones:

    ..src > elisp
      (% 7 5)

      (% 10 5)
    < src..

    La primer expresión devuelve 2 y la segunda 0.

    Para probar si el valor devuelto es cero o algún otro número, podemos
    usar la función @c{zerop}. Esta función devuelve @c{t} si su argumento
    que debe ser un número, es cero.

    ..srci > elisp
      > (zerop (% 7 5))
      nil
      > (zerop (% 10 5))
      t
    < srci..

    Por lo tanto, la siguiente expresión devolverá @c{t} si la altura del
    grafico es divisible por cinco:

    ..src > elisp
      (zerop (% altura 5))
    < src..

    (El valor de @c{altura}, por supuesto, se puede encontrar con
    @c{(apply 'max lista-de-numeros)}.)

    Por otro lado, si el valor de @c{altura} no es un múltiplo de cinco,
    queremos reajustar el valor al siguiente múltiplo de cinco. Esto
    es aritmética sencilla que usa funciones con las que ya estamos
    familiarizados. Primero, dividimos el valor de @c{altura} por cinco para
    determinar cuantas veces cinco entra en el número. De este modo, cinco
    entra en doce dos veces. Si agregamos uno a este cociente y lo multiplicamos
    por cinco, obtendremos el valor del siguiente múltiplo de cinco que es
    más grande que la altura. Cinco entra en doce dos veces. Se suma uno a
    dos, y se multiplica por cinco; el resultado es quince, que es el siguiente
    múltiplo de cinco que es mayor que doce. La expresión Lisp para esto es:

    ..src > elisp
      (* (1+ (/ altura 5)) 5)
    < src..

    Por ejemplo, al evaluar lo siguiente, el resultado es 15:

    ..src > elisp
      (* (1+ (/ 12 5)) 5)
    < src..

    A lo largo de esta discusión, hemos estado usando ‘cinco’ como el valor de
    espaciado para las etiquetas en el eje Y; pero es posible que queramos usar
    algún otro valor. Generalmente, debemos reemplazar ‘cinco’ con una variable
    a la que podamos asignar un valor. El mejor nombre que puedo pensar para
    esta variable es @c{distancia-entre-etiquetas-del-eje-Y}.

    Usando este término, y una expresión @c{if}, producimos lo siguiente:

    ..src > elisp
      (if (zerop (% altura distancia-entre-etiquetas-del-eje-Y))
          altura
        ;; else
        (* (1+ (/ altura distancia-entre-etiquetas-del-eje-Y))
           distancia-entre-etiquetas-del-eje-Y))
    < src..

    Esta expresión devuelve el valor de la @c{altura}, bien, si la altura es
    un múltiplo del valor de la @c{distancia-entre-etiquetas-del-eje-Y} o
    realizando un calculo si el valor de @c{altura} es igual al siguiente
    múltiplo superior del valor de la @c{distancia-entre-etiquetas-del-eje-Y}.

    Ahora podemos incluir esta expresión en la expresión @c{let} de la
    función @c{imprimir-grafico} (después de establecer el valor de la
    @c{distancia-entre-etiquetas-del-eje-Y}):

    ..src > elisp
      (defvar distancia-entre-etiquetas-del-eje-Y 5
        "Número de líneas desde una etiqueta del eje Y a la siguiente.")

      …
      (let* ((altura (apply 'max lista-de-numeros))
             (altura-de-la-linea-superior
              (if (zerop (% altura distancia-entre-etiquetas-del-eje-Y))
                  altura
                ;; else
                (* (1+ (/ altura distancia-entre-etiquetas-del-eje-Y))
                   distancia-entre-etiquetas-del-eje-Y)))
             (ancho-del-simbolo (length simbolo-en-blanco))))
      …
    < src..

    (Observa el uso de la función @c{let*}: el valor inicial de la @c{altura} se
    calcula una vez con la expresión @c{(apply 'max lista-de-numeros)} y luego
    se usa el resultado para calcular su valor final. Consulta la Seccion @l{#La
    expresión @c{let*}}, para conocer más sobre @c{let*}.)

*** Construir un elemento del eje Y

    Cuando imprimimos el eje vertical, queremos insertar cadenas como @'{5 - } y
    @'{10 - } cada cinco líneas. Además, queremos que los números y los guiones
    se alineen, por lo que los numeros mas cortos se deben rellenar con espacios
    en blanco. Si alguna de las cadenas utiliza numeros de dos dígitos, las
    cadenas con numeros de un solo dígito deben incluir un espacio en blanco
    delante del número.

    Para calcular la longitud del número, se usa la función @c{length}. Pero la
    función @c{length} solo funciona con una cadena, no con un número. Así que el
    número tiene que ser convertido de un número a una cadena. Esto se hace
    con la función @c{number-to-string}. Por ejemplo,

    ..srci > elisp
      > (length (number-to-string 35))
      2
      > (length (number-to-string 100))
      3
    < srci..

    (@c{number-to-string} tambien se llama @c{int-to-string}; verás este nombre
    alternativo en varios ficheros fuente.)

    Además, en cada etiqueta, cada número va seguido por una cadena @'{ - }, a
    la que llamaremos @c{marca-del-eje-Y}. Esta variable se define con
    @c{defvar}:

    ..src > elisp
      (defvar marca-del-eje-Y " - "
         "La Cadena que sigue al número en una etiqueta del eje Y.")
    < src..

    El tamaño de la etiqueta Y es la suma del tamaño de la marca del eje Y y el tamaño
    del número de la parte superior del grafico.

    ..src > elisp
      (length (concat (number-to-string altura) marca-del-eje-Y)))
    < src..

    Este valor será calculado por la función @c{imprimir-grafico} en su varlist
    como @c{ancho-completo-de-la-etiqueta-Y} y luego se pasara. (obverva que
    no pensamos incluir esto en el varlist cuando se propuso por primera vez.)

    Para hacer una etiqueta completa del eje vertical, se concatena la marca de
    etiqueta con un número; y los dos juntos pueden estar precedidos por uno o
    más espacios dependiendo de la longitud del número. La etiqueta consiste
    de tres partes: los espacios iniciales (opcionales), el número, y la
    marca. La función se pasa al valor del número para la fila específica, y
    el valor del ancho de la línea superior, que se calcula (solo una vez)
    por @c{imprimir-grafico}.

    ..src > elisp
      (defun elemento-del-eje-Y (numero ancho-completo-de-la-etiqueta-Y)
        "Construye una etiqueta NUMERADA
      Un elemento numerado se parece a esto ‘  5 - ’,
      y se rellena segun sea necesario, de modo que todos se
      alineen con el elemento para el número mas grande."
        (let* ((espacios-de-relleno
               (- ancho-completo-de-la-etiqueta-Y
                  (length
                   (concat (number-to-string numero)
                           marca-del-eje-Y)))))
          (concat
           (make-string espacios-de-relleno ? )
           (number-to-string numero)
           marca-del-eje-Y)))
    < src..

    La función @c{elemento-del-eje-Y} concatena juntos los espacios de relleno,
    si los hay; el número, como una cadena; y la marca de etiqueta.

    Para calcular cuantos espacios de relleno necesita la etiqueta, la función
    resta la longitud actual de la etiqueta––la longitud del numero más el tamaño de
    la marca––del ancho deseado para la etiqueta.

    Los espacios en blanco se insertan utilizando la función @c{make-string}.
    Esta función tiene dos argumentos: el primero dice cuan larga será la cadena
    y el segundo es un símbolo para el caracter a insertar, en un formato
    espcial. El formato es un signo de interrogacion seguido por un espacio en
    blanco, como este, @'c{? }. Consulta la Seccion @l{elisp.html#Character
    Type<>Tipo de Caracter} en @e{El Manual de Referencia de GNU Emacs Lisp}, para
    obtener una descripción de la sintaxis de los caracteres. (Por supuesto, es
    posible que quieras reemplazar el espacio en blanco por algún otro
    caracter…. Ya sabes qué hacer.)

    La función @c{number-to-string} se utiliza en la expresión de
    concatenación, para convertir el número en una cadena que se concatena
    con los espacios de relleno y la marca de la etiqueta.

*** Construir una columna del eje Y

    Las funciones anteriores proporcionan todas las herramientas necesarias
    para construir una función que genere una lista de cadenas enumeradas y
    en blanco para inserta como la etiqueta del eje vertical:

    ..src > elisp
      (defun columna-del-eje-Y (altura ancho-de-la-etiqueta)
        "Construye la lista de etiquetas y cadenas en blanco del eje Y.
      Para la ALTURA de la línea sobre la base y ANCHO-DE-LA-ETIQUETA."
        (let (eje-Y)
          (while (> altura 1)
            (if (zerop (% altura distancia-entre-etiquetas-del-eje-Y))
                ;; Insertar etiqueta.
                (setq eje-Y
                      (cons
                       (elemento-del-eje-Y altura ancho-de-la-etiqueta)
                       eje-Y))
              ;; de lo contrario, insertar espacios en blanco.
              (setq eje-Y
                    (cons
                     (make-string ancho-de-la-etiqueta ? )
                     eje-Y)))
            (setq altura (1- altura)))
          ;; Insertar línea base.
          (setq eje-Y
                (cons (elemento-del-eje-Y 1 ancho-de-la-etiqueta) eje-Y))
          (nreverse eje-Y)))
    < src..

    En esta función, empezamos con el valor de @c{altura} y restamos
    repetitivamente uno desde su valor. Después de cada resta, comprobamos si el
    valor es un multiplo integral de la @c{distancia-entre-etiquetas-del-eje-Y}.
    Si lo es, construimos una etiqueta numerada usando la función
    @c{elemento-del-eje-Y}; si no, construimos una etiqueta en blanco usando la
    función @c{make-string}. La línea base consiste en el número uno seguido por
    una marca de etiqueta.

*** La versión no del todo definitiva de @c{imprimir-eje-Y}

    La lista construida por la función @c{columna-del-eje-Y} se pasa a la
    función @c{imprimir-eje-Y}, que inserta la lista como una columna.

    ..src > elisp
      (defun imprimir-eje-Y (altura ancho-completo-de-la-etiqueta-Y)
        "Inserta el eje Y usando ALTURA y ANCHO-COMPLETO-DE-LA-ETIQUETA-Y.
      La altura debe ser la altura máxima del grafico.
      El ancho completo es el ancho del mayor elemento de la etiqueta"
      ;; El valor de altura y ancho-completo-de-la-etiqueta-Y
      ;; se pasan por ‘imprimir-grafico’.
        (let ((inicio (point)))
          (insert-rectangle
           (columna-del-eje-Y altura ancho-completo-de-la-etiqueta-Y))
          ;; Coloca el punto en posicion para inserta el grafico.
          (goto-char inicio)
          ;; Mueve el punto hacia adelante segun el valor de ancho-completo-de-la-etiqueta-Y
          (forward-char ancho-completo-de-la-etiqueta-Y)))
    < src..

    @c{imprimir-eje-Y} usa la función @c{insert-rectangle} para inserta el
    eje Y creado por la función @c{columna-del-eje-Y}. Además, coloca el
    punto en la posición correcta para imprimir el cuerpo del grafico.

    Puedes probar @c{imprimir-eje-Y}:

    1. Instala

       ..example >
         distancia-entre-etiquetas-del-eje-Y
         marca-del-eje-Y
         elemento-del-eje-Y
         columna-del-eje-Y
         imprimir-eje-Y
       < example..

    2. Copia la siguiente expresión:

       ..src > elisp
         (imprimir-eje-Y 12 5)
       < src..

    3. Cambia al búfer @f{*scratch*} y coloca el cursor donde quieras que inicien
       las etiquetas de los ejes.

    4. Presiona @k{M-:} @%c(eval-expression).

    5. coloca la expresión @c{imprimir-cuerpo-grafico} dentro del minibúfer con
       @k{C-y} @%c(yank).

    6. Presiona @k{RET} para evaluar la expresión


    Emacs imprimirá las etiquetas verticalmente, siendo la parte superior @'c{10 - }.
    (La función @c{imprimir-grafico} pasará el valor de
    @c{altura-de-la-linea-superior}, que en este caso terminara en 15,
    eliminando asi lo que podria aparecer como un error.)

** La función @c{imprimir-eje-X}

   Las etiquetas del eje X son muy parecidas a las etiquetas del eje Y, excepto
   que las marcas estan una linea por encima de los números. Las etiquetas
   deberian verse asi:

   ..example >
     |   |    |    |
     1   5   10   15
   < example..

   La primer marca está debajo de la primer columna del grafico y va precedida por
   varios espacios en blanco. Estos espacios proporcionan espacio en las
   filas para las etiquetas del eje Y. La segunda, tercera, cuarta,
   y subsiguientes marcas estan todas espaciadas por igual, de acuerdo al valor
   de @c{distancia-entre-etiquetas-del-eje-X}.

   La segunda fila del eje X consiste en números, precedidos por varios
   espacios en blanco y también separados de acuerdo al valor de la variable
   @c{distancia-entre-etiquetas-del-eje-X}.

   El valor de la variable @c{distancia-entre-etiquetas-del-eje-X} debe medirse
   en unidades de @c{ancho-del-simbolo}, ya que es posible que se desee cambiar el
   ancho de los símbolos utilizados para imprimir el cuerpo del grafico
   sin cambiar la forma en que se etiqueta el grafico.

   La función @c{imprimir-eje-X} se constituye más o menos del mismo modo
   que la función @c{imprimir-eje-Y} excepto que tiene dos líneas: la
   línea de marcas y los números. Escribiremos una función
   separada para imprimir cada línea y luego combinarlas con la función
   @c{imprimir-eje-X}.

   Este es un proceso de tres pasos:

   1. Escribir una función para imprimir las marcas del eje X,
      @c{imprimir-linea-de-marcas-del-eje-X}.

   2. Escribir una función para imprimir los números X,
      @c{imprimir-linea-numerada-del-eje-X}.

   3. Escribir una función para imprimir ambas líneas, la función
      @c{imprimir-eje-X}, usando @c{imprimir-linea-de-marcas-del-eje-X} e
      @c{imprimir-linea-numerada-del-eje-X}.

*** Marcas del Eje X

    La primera función debe imprimir las marcas de etiqueta del eje X. Debemos
    especificar las marcas en sí y su espaciado:

    ..src > elisp
      (defvar distancia-entre-etiquetas-del-eje-X
        (if (boundp 'simbolo-en-blanco)
            (* 5 (length simbolo-en-blanco)) 5)
        "Número de unidades de una etiqueta del eje X a la siguiente.")
    < src..

    (Ten en cuenta que el valor de @c{simbolo-en-blanco} lo establece otro
    @c{defvar}. El predicado @c{boundp} comprueba si ya ha sido establecido;
    @c{boundp} devuelve @c{nil} si no lo ha sido. Si @c{simbolo-en-blanco} no
    hubiera sido enlazado y no usaramos esta construcción condicional,
    estrariamos el depurador y veriamos un mensaje de error diciendo @'c{Debugger
    entered--Lisp error: (void-variable simbolo-en-blanco)}

    Aquí está el @c{defvar} para @c{marca-del-eje-X}:

    ..src > elisp
      (defvar marca-del-eje-X "|"
        "Cadena a insertar para apuntar a una columna en el eje X.")
    < src..

    El objetivo es crear una línea que se vea asi:

    ..example >
         |   |    |    |
    < example..

    La primer marca esta indentada de manera que quede debajo de la primera
    columna, que se indenta para dejar espacio para las etiquetas del eje Y.

    Un elemento de marca consiste en espacios en blanco que se extienden desde
    una marca a la siguiente más el símbolo de la propia marca. El número de
    espacios en blanco se determinan por el ancho del símbolo de marca y la
    @c{distancia-entre-etiquetas-del-eje-X}.

    El código se ve asi:

    ..src > elisp
      ;;; elemento-de-marca-del-eje-X
      …
      (concat
       (make-string
        ;; Crea una cadena de espacios en blanco.
        (-  (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X)
            (length marca-del-eje-X))
        ? )
       ;; Concatena los espacios en blanco con el símbolo de marca.
       marca-del-eje-X)
      …
    < src..

    A continuacion, determinamos cuantos espacios en blanco se necesitan para
    indentar la primer marca en la primera columna del grafico. Utilizamos el valor
    de @c{ancho-completo-de-la-etiqueta-Y} pasado por la función @c{imprimir-grafico}.

   El código para crear @c{espacios-de-relleno-del-eje-X} se ve asi:

    ..src > elisp
      ;; espacios-de-relleno-del-eje-X
      …
      (make-string ancho-completo-de-la-etiqueta-Y ? )
      …
    < src..

    También necesitamos determinar la longitud del eje horizontal, que es el
    tamaño de la lista de números, y el número de marcas del eje
    horizontal:

    ..src > elisp
      ;; longitud-X
      …
      (length lista-de-numeros)

      ;; longitud-marca
      …
      (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X)

      ;; numero-de-marcas-X
      (if (zerop (% (longitud-X longitud-marca)))
          (/ (longitud-X longitud-marca))
        (1+ (/ (longitud-X longitud-marca))))
    < src..

    Todo esto nos lleva directamente a la función para imprimir la linea de
    marcas del eje X:

    ..src > elisp
      (defun imprimir-linea-de-marcas-del-eje-X
        (numero-de-marcas-X espacios-de-relleno-del-eje-X elemento-de-marca-del-eje-X)
        "Imprime marcas para el eje X."
          (insert espacios-de-relleno-del-eje-X)
          (insert marca-del-eje-X)  ; Debajo de la primer columna.
          ;; Inserta la segunda marca en el lugar adecuado.
          (insert (concat
                   (make-string
                    (-  (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X)
                        ;; Inserta el espacio en blanco al segundo símbolo de marca.
                        (* 2 (length marca-del-eje-X)))
                    ? )
                   marca-del-eje-X))
          ;; Inserta las marcas restantes.
          (while (> numero-de-marcas-X 1)
            (insert elemento-de-marca-del-eje-X)
            (setq numero-de-marcas-X (1- numero-de-marcas-X))))
    < src..

    La línea de números es igualmente sencilla:

    Primero, creamos un elemento numerado con espacios en blanco antes de
    cada número:

    ..src > elisp
      (defun elemento-del-eje-X (numero)
        "Construye un elemento numerado del eje X."
        (let ((espacios-de-relleno
               (-  (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X)
                   (length (number-to-string numero)))))
          (concat (make-string espacios-de-relleno ? )
                  (number-to-string numero))))
    < src..

    A continuacion, creamos la función para imprimir la línea numerada,
    empezando con el número “1” para la primer columna:

    ..src > elisp
      (defun imprimir-linea-numerada-del-eje-X
        (numero-de-marcas-X espacios-de-relleno-del-eje-X)
        "Imprime linea de números del eje X"
        (let ((numero distancia-entre-etiquetas-del-eje-X))
          (insert espacios-de-relleno-del-eje-X)
          (insert "1")
          (insert (concat
                   (make-string
                    ;; Inserta espacios en blanco hasta el siguiente número.
                    (-  (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X) 2)
                    ? )
                   (number-to-string numero)))
          ;; Inserta los números restantes.
          (setq numero (+ numero distancia-entre-etiquetas-del-eje-X))
          (while (> numero-de-marcas-X 1)
            (insert (elemento-del-eje-X numero))
            (setq numero (+ numero distancia-entre-etiquetas-del-eje-X))
            (setq numero-de-marcas-X (1- numero-de-marcas-X)))))
    < src..

    Finalmente, necesitamos escribir @c{imprimir-eje-X} para usar
    @c{imprimir-linea-de-marcas-del-eje-X} e @c{imprimir-linea-numerada-del-eje-X}.

    La función debe determinar los valores locales de las variables utilizadas
    por @c{imprimir-linea-de-marcas-del-eje-X} e @c{imprimir-linea-numerada-del-eje-X}, y
    luego debe llamarlas. Ademas, debe imprimir el retorno de carro
    que separe las dos líneas.

    La función consiste de una varlist que especifica cinco variables
    locales, y llamadas a cada una de las dos funciones de impresion de líneas:

    ..src > elisp
      (defun imprimir-eje-X (lista-de-numeros)
        "Imprime las etiquetas del eje al tamaño de LISTA-DE-NUMEROS."
        (let* ((espacios-de-relleno
                (make-string ancho-completo-de-la-etiqueta-Y ? ))
               ;; ancho-del-simbolo es provisto por imprimir-cuerpo-grafico
               (longitud-marca (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X))
               (longitud-X (length lista-de-numeros))
               (marca-X
                (concat
                 (make-string
                  ;; Crea una cadena de espacios en blanco.
                  (-  (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X)
                      (length marca-del-eje-X))
                  ? )
                 ;; Concatena espacios en blanco con el símbolo de la marca.
                 marca-del-eje-X))
               (numero-de-marcas
                (if (zerop (% longitud-X longitud-marca))
                    (/ longitud-X longitud-marca)
                  (1+ (/ longitud-X longitud-marca)))))
          (imprimir-linea-de-marcas-del-eje-X numero-de-marcas espacios-de-relleno marca-X)
          (insert "\n")
          (imprimir-linea-numerada-del-eje-X numero-de-marcas espacios-de-relleno)))
    < src..

    Para probar @c{imprimir-eje-X}:

    1. Instala @c{marca-del-eje-X}, @c{distancia-entre-etiquetas-del-eje-X},
       @c{imprimir-linea-de-marcas-del-eje-X}, tambien @c{elemento-del-eje-X},
       @c{imprimir-linea-numerada-del-eje-X}, e @c{imprimir-eje-X}.

    2. Copia la siguiente expresión:

      ..src > elisp
        (progn
         (let ((ancho-completo-de-la-etiqueta-Y 5)
               (ancho-del-simbolo 1))
           (imprimir-eje-X
            '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16))))
      < src..

    3. Cambia al búfer @f{*scratch*} y coloca el cursor donde quieras que comiencen
       las etiquetas del eje.

    4. Presiona @k{M-:} @%c(eval-expression).

    5. Pega la expresión de prueba dentro del minibuffer con @k{C-y} @%c(yank).

    5. Presiona @k{RET} para evaluar la expresión

    Emacs imprimirá el eje horizontal así

    ..example >
           |   |    |    |    |
           1   5   10   15   20
    < example..

** Imprimir el grafico completo

   Ahora estamos casi listos para imprimir el grafico completo.

   La función para imprimir el grafico con las etiquetas apropiadas sigue el
   esquema que creamos anteriormente (Ver Sección @l{#Apéndice C: Un Grafico con Ejes
   Etiquetados}), pero con adiciones.

   Aquí está el esquema:

   ..src > elisp
     (defun imprimir-grafico (lista-de-numeros)
       "documentacion…"
       (let ((altura  …
             …))
         (imprimir-eje-Y altura … )
         (imprimir-cuerpo-grafico lista-de-numeros)
         (imprimir-eje-X … )))
   < src..

   La versión final es diferente de lo que planeamos de dos maneras: primero,
   contiene valores adicionales calculados una vez en la varlist;
   segundo, tiene una opción para específicar el encremento de las etiquetas por
   fila. Esta última funcionalidad resulta esencial; de otro modo, un
   grafico puede tener más filas de las que caben en una pantalla o en una hoja de
   papel.

   Esta nueva caracteristica requiere un cambio a la función
   @c{columna-del-eje-Y}, para añadirle un @c{paso-vertical}. Esta
   función se ve asi:

   ..src > elisp
     ;;; Versión Final.
     (defun columna-del-eje-Y
       (altura ancho-de-la-etiqueta &optional paso-vertical)
       "Construye una lista de etiquetas para el eje Y.
     ALTURA es la altura máxima del grafico.
     ANCHO-DE-LA-ETIQUETA es el ancho máximo de la etiqueta.
     PASO-VERTICAL, una opción, es un entero positivo que
     especifica cuanto se incrementa una etiqueta del eje Y en
     cada línea. Por ejemplo, un paso de 5 significa que cada
     línea es cinco unidades del grafico."
       (let (eje-Y
             (numero-por-linea (or paso-vertical 1)))
         (while (> altura 1)
           (if (zerop (% altura distancia-entre-etiquetas-del-eje-Y))
               ;; Inserta etiqueta.
               (setq eje-Y
                     (cons
                      (elemento-del-eje-Y
                       (* altura numero-por-linea)
                       ancho-de-la-etiqueta)
                      eje-Y))
             ;; de otra forma, inserta espacios en blanco.
             (setq eje-Y
                   (cons
                    (make-string ancho-de-la-etiqueta ? )
                    eje-Y)))
           (setq altura (1- altura)))
         ;; Inserta línea base.
         (setq eje-Y (cons (elemento-del-eje-Y
                             (or paso-vertical 1)
                             ancho-de-la-etiqueta)
                            eje-Y))
         (nreverse eje-Y)))
   < src..

   Los valores para la altura máxima del grafico y el ancho de un símbolo se
   calculan por medio de @c{imprimir-grafico} es su expresión @c{let}; por lo tanto,
   @c{imprimir-cuerpo-grafico} debe cambiarse para aceptarlos.

   ..src > elisp
     ;;; Versión Final.
     (defun imprimir-cuerpo-grafico (lista-de-numeros altura ancho-del-simbolo)
       "Imprime un gráfico de barras de la LISTA-DE-NUMEROS.
     La lista-de-numeros consiste en los valores del eje Y.
     ALTURA es la altura máxima del grafico.
     ANCHO-DEL-SIMBOLO es el número de cada columna."
       (let (desde-la-posicion)
         (while lista-de-numeros
           (setq desde-la-posicion (point))
           (insert-rectangle
            (columna-del-grafico altura (car lista-de-numeros)))
           (goto-char desde-la-posicion)
           (forward-char ancho-del-simbolo)
           ;; Dibuja el grafico columna por columna.
             (sit-for 0)
             (setq lista-de-numeros (cdr lista-de-numeros)))
         ;; Coloca el punto para las etiquetas del eje X.
         (forward-line altura)
         (insert "\n")))
   < src..

   Finalmente, el código para la función @c{imprimir-grafico}:

   ..src > elisp
     ;;; Versión Final.
     (defun imprimir-grafico
       (lista-de-numeros &optional paso-vertical)
       "Imprime el gráfico de barras etiquetado de la LISTA-DE-NUMEROS.
     La lista-de-numeros consiste en los valores del eje Y.

     Opcionalmente, PASO-VERTICAL, un entero positivo, especifica cuanto
     se incrementa la etiqueta del eje Y en cada línea. Por ejemplo, un
     paso de 5 significa que cada fila tiene cinco unidades."
       (let* ((ancho-del-simbolo (length simbolo-en-blanco))
              ;; ALTURA es tanto el número más grande
              ;; como el número con mas digitos.
              (altura (apply 'max lista-de-numeros))
              (altura-de-la-linea-superior
               (if (zerop (% altura distancia-entre-etiquetas-del-eje-Y))
                   altura
                 ;; else
                 (* (1+ (/ altura distancia-entre-etiquetas-del-eje-Y))
                    distancia-entre-etiquetas-del-eje-Y)))
              (paso-vertical (or paso-vertical 1))
              (ancho-completo-de-la-etiqueta-Y
               (length
                (concat
                 (number-to-string
                  (* altura-de-la-linea-superior paso-vertical))
                 marca-del-eje-Y))))

         (imprimir-eje-Y
          altura-de-la-linea-superior ancho-completo-de-la-etiqueta-Y paso-vertical)
         (imprimir-cuerpo-grafico
          lista-de-numeros altura-de-la-linea-superior ancho-del-simbolo)
         (imprimir-eje-X lista-de-numeros)))
   < src..

*** Probando @c{imprimir-grafico}

    Podemos probar la función @c{imprimir-grafico} con una pequeña lista de
    números:

    1. Instala las versiones finales de @c{columna-del-eje-Y},
       @c{imprimir-cuerpo-grafico}, e @c{imprimir-grafico} (además del resto del código.)

    2. Copia la siguiente expresión:

       ..src > elisp
         (imprimir-grafico '(3 2 5 6 7 5 3 4 6 4 3 2 1))
       < src..

    3. Cambia al búfer @f{*scratch*} y coloca el cursor donde quieras que inicien
       las etiquetas de los ejes.

    4. presiona @k{M-:} @%c(eval-expression).

    5. Pegua la expresión de prueba dentro del minibuffer con @k{C-y}
       @%c(yank).

    6. Presiona @k{RET} para evaluar la expresión


    Emacs imprimirá un grafico con este aspecto:

    ..example >
      10 -


               *
              **   *
       5 -   ****  *
             **** ***
           * *********
           ************
       1 - *************

           |   |    |    |
           1   5   10   15
    < example..



    Por otro lado, si se pasa a @c{imprimir-grafico} un valor de @c{paso-vertical}
    de 2, evaluando esta expresión:

    ..src > elisp
      (imprimir-grafico '(3 2 5 6 7 5 3 4 6 4 3 2 1) 2)
    < src..

    El grafico tiene el siguiente aspecto:

    ..example >
      20 -


               *
              **   *
      10 -   ****  *
             **** ***
           * *********
           ************
       2 - *************

           |   |    |    |
           1   5   10   15
    < example..

    (Una pregunta: ¿es el ‘2’ en la parte inferior del eje vertical un error o una
    caracteristica? Si crees que es un error, y deberia ser un ‘1’, (o incluso
    un ‘0’), puedes modificar el codigo.)

*** Graficar números de palabras y símbolos

    Ahora el gráfico para el que todo este código fué escrito: un gráfico que
    muestra cuantas definiciones de función contienen menos de 10 palabras y
    símbolos, cuantas contienen entre 10 y 19, cuantas entre 20 y 29 palabras,
    y así sucesivamente.

    Este es un proceso de varios pasos. Primero asegúrate que has cargado
    todo el código requerido.

    Es una buena idea restablecer el valor de @c{cima-de-rangos} en
    caso de que lo hayas asignado a algún valor diferente. Puedes evaluar lo
    siguiente:

    ..src > elisp
      (setq cima-de-rangos
       '(10  20  30  40  50
         60  70  80  90 100
        110 120 130 140 150
        160 170 180 190 200
        210 220 230 240 250
        260 270 280 290 300))
    < src..

    Luego crea una lista del número de palabras y símbolos en cada
    rango.

    Evalúa lo siguiente:

    ..src > elisp
      (setq lista-para-el-grafico
             (definiciones-por-rango
               (sort
                (lista-de-longitudes-de-muchos-ficheros-recursiva
                 (directory-files "/usr/local/emacs/lisp"
                                  t ".+el$"))
                '<)
               cima-de-rangos))
    < src..

    En mi vieja máquina, esto tardaba una hora. Veia atraves de 303 ficheros
    Lisp en mi copia de Emacs version 19.23. Después de toda esa
    computación, @c{lista-para-el-grafico} tenía este valor:

    ..src > elisp
      (537 1027 955 785 594 483 349 292 224 199 166 120 116 99
       90 80 67 48 52 45 41 33 28 26 25 20 12 28 11 13 220)
    < src..

    Esto significa que mi copia de Emacs tiene 537 definiciones de funcion con
    poco menos de 10 palabras o símbolos en ellas, 1027 definiciones con 10 a
    19 palabras o símbolos, 955 con 20 a 29, etc.

    Claramente, con solo mirar esta lista se puede ver que la mayoría de
    definiciones de función contienen de diez a treinta palabras y símbolos.

    Ahora a imprimirla. No queremos imprimir un grafico de 1030 líneas de alto
    …. En su lugar, debemos imprimir un grafico que tenga menos de venticinco líneas
    de alto. Un grafico cuya altura puede ser mostrada en casi cualquier
    monitor, e imprimirse fácilmente en una hoja de papel.

    Esto significa que cada valor en @c{lista-para-el-grafico} debe reducirse a un
    quincuagesimo de su valor actual.

    Aquí hay una breve función para hacer exactamente eso, usando dos funciones que no
    hemos visto todavía, @c{mapcar} y @c{lambda}.

    ..src > elisp
      (defun un-cincuentavo (rango-completo)
        "Devuelve una lista con la quincuagesima parte de cada numero."
       (mapcar '(lambda (arg) (/ arg 50)) rango-completo))
    < src..

*** Una expresión @c{lambda}: Anonimato útil

    @c{lambda} es el símbolo para una función anónima, una función sin
    nombre. Cada vez que se use una función anónima, es necesario incluir
    todo su cuerpo.

    De este modo,

    ..src > elisp
      (lambda (arg) (/ arg 50))
    < src..

    es una definición de función que dice ‘devuelve el valor resultante de
    dividir lo que se pasa como @c{arg} por 50’.

    Anteriormente, por ejemplo, teniamos una función @c{multiplicar-por-siete};
    multiplica su argumento por 7. Esta función es similar, excepto que
    divide su argumento por 50; y, no tiene nombre. El equivalente anónimo
    de @c{multiplicar-por-siete} es:

    ..src > elisp
      (lambda (numero) (* 7 numero))
    < src..

    (Consulta la Seccion @l{#La forma especial @c{defun}}.)

    Si queremos multiplicar 3 por 7, podemos escribir:

    ..art >
      (multiplicar-por-siete 3)
       \___________________/ ^
                 |           |
              función    argumento
    < art..

    Esta expresión devuelve 21.

    De manera similar, podemos escribir:

    ..art >
      ((lambda (numero) (* 7 numero)) 3)
       \____________________________/ ^
                     |                |
             función anónima     argumento
    < art..

    Si queremos dividir 100 por 50, podemos escribir:

    ..art >
      ((lambda (arg) (/ arg 50)) 100)
       \______________________/  \_/
                   |              |
           función anónima    argumento
    < art..

    Esta expresión devuelve 2. El 100 se pasa a la función, que divide
    este número por 50.

     Cosulta la Seccion @l{elisp.html#Lambda Expressions<>Expresiones Lambda} en
     @e{El Manual de Referencia de GNU Emacs Lisp}, para más informacion acerca de
     @c{lambda}. Lisp y las expresiones Lambda se derivan del Cálculo Lambda.

*** La función @c{mapcar}

    @c{mapcar} es una función que llama a su primer argumento con cada
    elemento de su segundo argumento. El segundo argumento debe ser una
    secuencia.

    La parte @'{map} del nombre viene de la frase matemática, ‘mapeo sobre
    un dominio’, lo que significa aplicar una función a cada uno de
    los elementos en un dominio. La frase matemática se basa en la
    metáfora de un topografo que camina, un paso a la vez, sobre
    un área que está mapeando. Y @'{car}, por supuesto, proviene de la noción
    Lisp del primer elemento de una lista.

    Por ejemplo,

    ..srci > elisp
      > (mapcar '1+ '(2 4 6))
      (3 5 7)
    < srci..

    La función @c{1+} añade uno a su argumento, se ejecuta en @e{cada} elemento de
    la lista, y se devuelve una nueva lista.

    En contraste con @c{apply}, que aplica su primer argumento a todos los
    demas. (Consulta la Seccion @l{#Preparar un grafico}, para una explicación
    de @c{apply}.)

    En la definición de @c{un-cincuentavo}, el primer argumento es la función
    anónima:

    ..src > elisp
      (lambda (arg) (/ arg 50))
    < src..

    y el segundo argumento es @c{rango-completo}, que será vinculado a
    @c{lista-para-el-grafico}.

    La expresión completa se ve asi:

    ..src > elisp
      (mapcar (lambda (arg) (/ arg 50)) rango-completo))
    < src..

    Consulta la Seccion @l{elisp.html#Mapping Functions<>Mapeando Funciones} en
    @e{El Manual de Referencia de GNU Emacs Lisp}, para más informacion sobre
    @c{mapcar}.

    Usando la función @c{un-cincuentavo}, podemos generar una lista en la que
    cada elemento es un cincuentavo del tamaño del elemento correspondiente
    en la @c{lista-para-el-grafico}.

    ..src > elisp
      (setq cincuentavo-de-lista-para-el-grafico
            (un-cincuentavo lista-para-el-grafico))
    < src..

    La lista resultante luce asi:

    ..src > elisp
      (10 20 19 15 11 9 6 5 4 3 3 2 2
       1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 4)
    < src..

    ¡Ya estamos casi listos para imprimir! (También notamos la
    pérdida de información: muchos de los rangos mas altos son 0, lo que
    significa que menos de 50 funciones tenían tantas palabras o
    símbolos––pero no necesariamente significa que niguna tenía tantas
    palabras o símbolos.)

*** Otro error … más insidioso

    ¡Dije ‘casi listos para imprimir’! De acuerdo, hay un error en la
    función @c{imprimir-grafico} …. Tiene una opción @c{paso-vertical}, pero
    no una opción @c{paso-horizontal}. La escala de @c{cima-de-rango} va desde
    10 a 300 por decenas. Pero la función @c{imprimir-grafico} se imprimirá solo
    por unos.

    Este es un ejemplo clásico de lo que algunos consideramos el tipo de error más
    insidioso, el error de omisión. Este no es el tipo de error que se
    puede encontrar estudiando el código, ya que no esta en el código; es una
    caracteristica omitida. Tus mejores acciones son probar tu programa temprano
    y con frecuencia; e intentar arreglar, tanto como se pueda, escribir
    código que sea fácil de comprender y fácil de cambiar. Intenta ser
    consciente, siempre que puedas, de que todo lo que has escrito, @e{será}
    reescrito, si no pronto, eventualmente. Una dura máxima a seguir.

    Es la función @c{imprimir-linea-numerada-del-eje-X} la que necesita trabajo;
    y luego hay que adaptar las funciones @c{imprimir-eje-X} e @c{imprimir-grafico}.
    No hay mucho que hacer; hay una cosa buena: los números deben
    alinearse con marcas de etiquetado. Esto requiere un poco de reflexion.

    Aquí está @c{imprimir-linea-numerada-del-eje-X} corregido:

    ..src > elisp
      (defun imprimir-linea-numerada-del-eje-X
        (numero-de-marcas-X espacios-de-relleno-del-eje-X
         &optional paso-horizontal)
        "Imprime linea de números del eje X"
        (let ((numero distancia-entre-etiquetas-del-eje-X)
              (paso-horizontal (or paso-horizontal 1)))
          (insert espacios-de-relleno-del-eje-X)
          ;; Elimina espacios de relleno sobrantes.
          (delete-char
           (- (1-
               (length (number-to-string paso-horizontal)))))
          (insert (concat
                   (make-string
                    ;; Inserta espacio en blanco.
                    (-  (* ancho-del-simbolo
                           distancia-entre-etiquetas-del-eje-X)
                        (1-
                         (length
                          (number-to-string paso-horizontal)))
                        2)
                    ? )
                   (number-to-string
                    (* numero paso-horizontal))))
          ;; Inserta los números restantes.
          (setq numero (+ numero distancia-entre-etiquetas-del-eje-X))
          (while (> numero-de-marcas-X 1)
            (insert (elemento-del-eje-X
                     (* numero paso-horizontal)))
            (setq numero (+ numero distancia-entre-etiquetas-del-eje-X))
            (setq numero-de-marcas-X (1- numero-de-marcas-X)))))
    < src..

    A continuacion, las líneas que cambian en @c{imprimir-eje-X} e
    @c{imprimir-grafico}.

    ..src > elisp
      (defun imprimir-eje-X (lista-de-numeros paso-horizontal)
        …
          (imprimir-linea-numerada-del-eje-X
           numero-de-marcas espacios-de-relleno paso-horizontal))

      (defun imprimir-grafico
        (lista-de-numeros
         &optional paso-vertical paso-horizontal)
        …
          (imprimir-eje-X lista-de-numeros paso-horizontal))
    < src..

*** El gráfico impreso

    Cuando está hecho e instalado, puedes llamar al comando
    @c{imprimir-grafico} asi:

    ..src > elisp
      (imprimir-grafico cincuentavo-de-lista-para-el-grafico 50 10)
    < src..

    Aquí está el gráfico:

    ..example >
      1000 -  *
              **
              **
              **
              **
       750 -  ***
              ***
              ***
              ***
              ****
       500 - *****
             ******
             ******
             ******
             *******
       250 - ********
             *********                     *
             ***********                   *
             *************                 *
        50 - ***************** *           *
             |   |    |    |    |    |    |    |
            10  50  100  150  200  250  300  350
    < example..


    El grupo mas grande de funciones contienen de 10 a 19 palabras y símbolos.

* Apéndice D: Software Libre y Manuales Libres @%b{por Richard M. Stallman}

  La mayor deficiencia de los sistemas operativos libres no está en el
  software––sino en la falta de buenos manuales libres que podamos incluir en
  estos sistemas. Muchos de nuestros programas más importantes no vienen con
  manuales completos. La documentación es una parte esencial de cualquier
  paquete de software; cuando un paquete de software libre no viene con un
  manual libre, eso es un gran vacio. Hoy en dia tenemos muchos vacios de este tipo.

  Érase una vez, hace muchos años, que pense que aprendería Perl. Consegui
  una copia de un manual libre, pero me resulto difícil de leer. Cuando
  pregunte a los usuarios de Perl sobre alternativas, me dijeron que
  habia mejores manuales introductorios––pero estos no eran libres.

  ¿Por qué fue asi? Los autores de los buenos manuales los habían escrito
  para O'Reilly Associates, que los publicaron con términos restrictivos––sin
  copia, sin modificacion, sin ficheros fuente disponibles––que los
  excluyen de la comunidad del software libre.

  No era la primera vez que ocurrían estas cosas, y para nuestra comunidad es
  una gran pérdida que estaba lejos de ser la ultima. Las editoriales de
  manuales privativos han logrado que muchos autores restrinjan sus manuales
  desde entonces. Muchas veces he oido a un habil usuario de GNU hablarme con
  entusiasmo de un manual que está escribiendo, con el que espera ayudar al
  proyecto GNU––y luego mis esperanzas se vieron frustradas, mientras procedia
  a explicarme que habia firmado un contrato con una editorial que
  lo restringiría para que no pudieramos usarlo.

  Debido a que escribir buen inglés es una habilidad poco comun entre los
  programadores, no podemos darnos el lujo de perder manuales de esta manera.

  La documentación, como el software, es una cuestión de libertad, no de
  precio. El problema con estos manuales no eran que O'Reilly Associates
  impusiera un precio por las copias impresas––eso en si mismo esta bien. La
  Free Software Foundation tambien @l{http://shop.fsf.org<>vende copias impresas} de los
  @l{http://www.gnu.org/doc/doc.html<>manuales libres de GNU}. Pero los
  manuales de GNU están disponibles en forma de código fuente, mientras que
  estos manuales están disponibles solo en papel. Los manuales de GNU vienen con
  permiso para copiar y modificar; los manuales de Perl no. Estas restricciones
  son un problema.

  El criterio para un manual libre es practicamente el mismo que para el
  software libre: es una cuestión de dar a todos los usuarios ciertas
  libertades. Se debe permitir la redistribución (incluida la redistribución
  comercial), de modo que el manual puede acompañar cada copia del programa, en linea o
  en papel. El permiso para la modificacion tambien es crucial.

  Como regla general, no creo que sea esencial que la gente tenga permiso para
  modificar todo tipo de artículos y libros. Las cuestiones relativa a los
  escritos no son necesariamente las mismas que las del software. Por ejemplo,
  no creo que usted o yo estemos obligados a dar permisos para modificar artículos como
  este, que describen nuestras acciones y nuestros puntos de vista.

  Pero hay una razón particular por la qué la libertad de modificar es
  crucial para la documentación del software libre. Cuando las personas
  ejercen su derecho a modificar el software, y añadir o cambiar sus
  funcionalidades, si son concienzudos, tambien cambiarán el manual––de
  modo que puedan proporcionar documentación precisa y usable con el programa
  modificado. Un manual que prohibe a los programadores ser concienzudos y
  terminar el trabajo, o más precisamente requiere que escriban un nuevo manual
  desde cero si cambian el programa, no se ajusta a las necesidades de
  nuestra comunidad.

  Si bien una prohibicion general de la modificación es inaceptable, algunos
  tipos de límites sobre el método de modificacion no plantea ningun
  problema. Por ejemplo, los requisitos para preservar el aviso de copyright del
  autor original, los términos de distribución, o la lista de autores, estén
  bien. Tampoco es un problemas requerir que las versiones modificadas
  incluyan un aviso de que fueron modificadas, incluso para tener secciones enteras que
  no pueden ser eliminadas o cambiadas, siempre y cuando estas secciones traten
  asuntos no técnicos. (Algunos manuales de GNU los tienen.)

  Este tipo de restricciones no son un problema porque, en la
  práctica, no impiden que el programador concienzudo adapte el manual
  al programa modificado. En otras palabras, no impiden que la
  comunidad del software libre haga pleno uso del manual.

  Sin embargo, debe ser posible modificar todo el contenido técnico del
  manual, y luego distribuir el resultado en todos los medios habituales,
  a través de todos los canales; de otro modo, las restricciones
  bloquean la comunidad, el manual no es libre, por lo que necesitamos otro
  manual.

  Desafortunadamente, con frecuencia es dificil encontrar a alguien que escriba
  otro manual cuando existe el privativo. El obstáculo es que muchos usuarios
  piensan que un manual privativo es lo suficientemente bueno––por lo que no ven
  la necesidad de escribir un manual libre. Ellos no ven que el sistema
  operativo tiene un hueco que necesita se llenado.

  ¿Por qué los usuarios piensan que los manuales privativos son lo
  suficientemente buenos? Algunos no han considerado el tema. Espero que
  este artículo haga algo para cambiar eso.

  Otros usuarios considera que los manuales privativos son aceptables por la
  misma razón que muchas personas consideran que el software privativo es
  aceptable: juzgan en términos puramente prácticos, sin usar la libertad
  como criterio. Estas personas tiene derecho a sus opiniones, pero como esas
  opiniones provienen de valores que no incluyen la libertad, no son una guia
  para aquellos de nosotros que valoramos la libertad.

  Por favor, haga correr la voz sobre este tema. Seguimos perdiendo manuales
  debido a la publicacion privativa. Si hacemos correr la voz de que los manuales
  privativos no son suficientes, quizás la siguiente persona que quiera ayudar a
  GNU escribiendo documentación se dara cuenta, antes de que sea demasiado
  tarde, que sobre todo debe hacerlo libre.

  También podemos animar a las editoriales comerciales a vender manuales libres
  o con copyleft en lugar de manuales privativos. Una forma de ayudar es
  comprobar los términos de distribución de un manual antes de comprarlo, y
  preferir manuales con copyleft a los no copyleft.

  Nota: La Free Software Foundation mantiene una página en su sitio
  Web que lista libros libres disponibles en otras editoriales:
  @l{http://www.gnu.org/doc/other-free-books.html}

* Appendix E: GNU Free Documentation License

  ..center >
    Version 1.3, 3 November 2008
  < center..

  Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
  <@l(http://fsf.org/)>

  Everyone is permitted to copy and distribute verbatim copies of this
  license document, but changing it is not allowed.

** 0. PREAMBLE

   The purpose of this License is to make a manual, textbook, or other
   functional and useful document "free" in the sense of freedom: to assure
   everyone the effective freedom to copy and redistribute it, with or
   without modifying it, either commercially or noncommercially.
   Secondarily, this License preserves for the author and publisher a way to
   get credit for their work, while not being considered responsible for
   modifications made by others.

   This License is a kind of "copyleft", which means that derivative works of
   the document must themselves be free in the same sense. It complements
   the GNU General Public License, which is a copyleft license designed for
   free software.

   We have designed this License in order to use it for manuals for free
   software, because free software needs free documentation: a free program
   should come with manuals providing the same freedoms that the software
   does. But this License is not limited to software manuals; it can be used
   for any textual work, regardless of subject matter or whether it is
   published as a printed book. We recommend this License principally for
   works whose purpose is instruction or reference.

** 1. APPLICABILITY AND DEFINITIONS

   This License applies to any manual or other work, in any medium, that
   contains a notice placed by the copyright holder saying it can be
   distributed under the terms of this License. Such a notice grants a
   world-wide, royalty-free license, unlimited in duration, to use that work
   under the conditions stated herein. The "Document", below, refers to any
   such manual or work. Any member of the public is a licensee, and is
   addressed as "you". You accept the license if you copy, modify or
   distribute the work in a way requiring permission under copyright law.

   A "Modified Version" of the Document means any work containing the
   Document or a portion of it, either copied verbatim, or with modifications
   and/or translated into another language.

   A "Secondary Section" is a named appendix or a front-matter section of the
   Document that deals exclusively with the relationship of the publishers or
   authors of the Document to the Document's overall subject (or to related
   matters) and contains nothing that could fall directly within that overall
   subject.  (Thus, if the Document is in part a textbook of mathematics, a
   Secondary Section may not explain any mathematics.)  The relationship
   could be a matter of historical connection with the subject or with
   related matters, or of legal, commercial, philosophical, ethical or
   political position regarding them.

   The "Invariant Sections" are certain Secondary Sections whose titles are
   designated, as being those of Invariant Sections, in the notice that says
   that the Document is released under this License. If a section does not
   fit the above definition of Secondary then it is not allowed to be
   designated as Invariant. The Document may contain zero Invariant
   Sections. If the Document does not identify any Invariant Sections then
   there are none.

   The "Cover Texts" are certain short passages of text that are listed, as
   Front-Cover Texts or Back-Cover Texts, in the notice that says that the
   Document is released under this License. A Front-Cover Text may be at
   most 5 words, and a Back-Cover Text may be at most 25 words.

   A "Transparent" copy of the Document means a machine-readable copy,
   represented in a format whose specification is available to the general
   public, that is suitable for revising the document straightforwardly with
   generic text editors or (for images composed of pixels) generic paint
   programs or (for drawings) some widely available drawing editor, and that
   is suitable for input to text formatters or for automatic translation to a
   variety of formats suitable for input to text formatters. A copy made in
   an otherwise Transparent file format whose markup, or absence of markup,
   has been arranged to thwart or discourage subsequent modification by
   readers is not Transparent. An image format is not Transparent if used
   for any substantial amount of text. A copy that is not "Transparent" is
   called "Opaque".

   Examples of suitable formats for Transparent copies include plain ASCII
   without markup, Texinfo input format, LaTeX input format, SGML or XML
   using a publicly available DTD, and standard-conforming simple HTML,
   PostScript or PDF designed for human modification. Examples of
   transparent image formats include PNG, XCF and JPG. Opaque formats
   include proprietary formats that can be read and edited only by
   proprietary word processors, SGML or XML for which the DTD and/or
   processing tools are not generally available, and the machine-generated
   HTML, PostScript or PDF produced by some word processors for output
   purposes only.

   The "Title Page" means, for a printed book, the title page itself, plus
   such following pages as are needed to hold, legibly, the material this
   License requires to appear in the title page. For works in formats which
   do not have any title page as such, "Title Page" means the text near the
   most prominent appearance of the work's title, preceding the beginning of
   the body of the text.

   The "publisher" means any person or entity that distributes copies of the
   Document to the public.

   A section "Entitled XYZ" means a named subunit of the Document whose title
   either is precisely XYZ or contains XYZ in parentheses following text that
   translates XYZ in another language.  (Here XYZ stands for a specific
   section name mentioned below, such as "Acknowledgements", "Dedications",
   "Endorsements", or "History".)  To "Preserve the Title" of such a section
   when you modify the Document means that it remains a section "Entitled
   XYZ" according to this definition.

   The Document may include Warranty Disclaimers next to the notice which
   states that this License applies to the Document. These Warranty
   Disclaimers are considered to be included by reference in this License,
   but only as regards disclaiming warranties: any other implication that
   these Warranty Disclaimers may have is void and has no effect on the
   meaning of this License.

** 2. VERBATIM COPYING

   You may copy and distribute the Document in any medium, either
   commercially or noncommercially, provided that this License, the copyright
   notices, and the license notice saying this License applies to the
   Document are reproduced in all copies, and that you add no other
   conditions whatsoever to those of this License. You may not use technical
   measures to obstruct or control the reading or further copying of the
   copies you make or distribute. However, you may accept compensation in
   exchange for copies. If you distribute a large enough number of copies
   you must also follow the conditions in section 3.

   You may also lend copies, under the same conditions stated above, and you
   may publicly display copies.

** 3. COPYING IN QUANTITY

   If you publish printed copies (or copies in media that commonly have
   printed covers) of the Document, numbering more than 100, and the
   Document's license notice requires Cover Texts, you must enclose the
   copies in covers that carry, clearly and legibly, all these Cover Texts:
   Front-Cover Texts on the front cover, and Back-Cover Texts on the back
   cover. Both covers must also clearly and legibly identify you as the
   publisher of these copies. The front cover must present the full title
   with all words of the title equally prominent and visible. You may add
   other material on the covers in addition. Copying with changes limited to
   the covers, as long as they preserve the title of the Document and satisfy
   these conditions, can be treated as verbatim copying in other respects.

   If the required texts for either cover are too voluminous to fit legibly,
   you should put the first ones listed (as many as fit reasonably) on the
   actual cover, and continue the rest onto adjacent pages.

   If you publish or distribute Opaque copies of the Document numbering more
   than 100, you must either include a machine-readable Transparent copy
   along with each Opaque copy, or state in or with each Opaque copy a
   computer-network location from which the general network-using public has
   access to download using public-standard network protocols a complete
   Transparent copy of the Document, free of added material. If you use the
   latter option, you must take reasonably prudent steps, when you begin
   distribution of Opaque copies in quantity, to ensure that this Transparent
   copy will remain thus accessible at the stated location until at least one
   year after the last time you distribute an Opaque copy (directly or
   through your agents or retailers) of that edition to the public.

   It is requested, but not required, that you contact the authors of the
   Document well before redistributing any large number of copies, to give
   them a chance to provide you with an updated version of the Document.

** 4. MODIFICATIONS

   You may copy and distribute a Modified Version of the Document under the
   conditions of sections 2 and 3 above, provided that you release the
   Modified Version under precisely this License, with the Modified Version
   filling the role of the Document, thus licensing distribution and
   modification of the Modified Version to whoever possesses a copy of it.
   In addition, you must do these things in the Modified Version:

   A. Use in the Title Page (and on the covers, if any) a title distinct from
      that of the Document, and from those of previous versions (which
      should, if there were any, be listed in the History section of the
      Document). You may use the same title as a previous version if the
      original publisher of that version gives permission.

   B. List on the Title Page, as authors, one or more persons or entities
      responsible for authorship of the modifications in the Modified
      Version, together with at least five of the principal authors of the
      Document (all of its principal authors, if it has fewer than five),
      unless they release you from this requirement.

   C. State on the Title page the name of the publisher of the Modified
      Version, as the publisher.

   D. Preserve all the copyright notices of the Document.

   E. Add an appropriate copyright notice for your modifications adjacent to
      the other copyright notices.

   F. Include, immediately after the copyright notices, a license notice
      giving the public permission to use the Modified Version under the
      terms of this License, in the form shown in the Addendum below.

   G. Preserve in that license notice the full lists of Invariant Sections
      and required Cover Texts given in the Document's license notice.

   H. Include an unaltered copy of this License.

   I. Preserve the section Entitled "History", Preserve its Title, and add to
      it an item stating at least the title, year, new authors, and publisher
      of the Modified Version as given on the Title Page. If there is no
      section Entitled "History" in the Document, create one stating the
      title, year, authors, and publisher of the Document as given on its
      Title Page, then add an item describing the Modified Version as stated
      in the previous sentence.

   J. Preserve the network location, if any, given in the Document for public
      access to a Transparent copy of the Document, and likewise the network
      locations given in the Document for previous versions it was based on.
      These may be placed in the "History" section. You may omit a network
      location for a work that was published at least four years before the
      Document itself, or if the original publisher of the version it refers
      to gives permission.

   K. For any section Entitled "Acknowledgements" or "Dedications", Preserve
      the Title of the section, and preserve in the section all the substance
      and tone of each of the contributor acknowledgements and/or dedications
      given therein.

   L. Preserve all the Invariant Sections of the Document, unaltered in their
      text and in their titles. Section numbers or the equivalent are not
      considered part of the section titles.

   M. Delete any section Entitled "Endorsements". Such a section may not be
      included in the Modified Version.

   N. Do not retitle any existing section to be Entitled "Endorsements" or to
      conflict in title with any Invariant Section.

   O. Preserve any Warranty Disclaimers.


   If the Modified Version includes new front-matter sections or appendices
   that qualify as Secondary Sections and contain no material copied from the
   Document, you may at your option designate some or all of these sections
   as invariant. To do this, add their titles to the list of Invariant
   Sections in the Modified Version's license notice. These titles must be
   distinct from any other section titles.

   You may add a section Entitled "Endorsements", provided it contains
   nothing but endorsements of your Modified Version by various parties--for
   example, statements of peer review or that the text has been approved by
   an organization as the authoritative definition of a standard.

   You may add a passage of up to five words as a Front-Cover Text, and a
   passage of up to 25 words as a Back-Cover Text, to the end of the list of
   Cover Texts in the Modified Version. Only one passage of Front-Cover Text
   and one of Back-Cover Text may be added by (or through arrangements made
   by) any one entity. If the Document already includes a cover text for the
   same cover, previously added by you or by arrangement made by the same
   entity you are acting on behalf of, you may not add another; but you may
   replace the old one, on explicit permission from the previous publisher
   that added the old one.

   The author(s) and publisher(s) of the Document do not by this License give
   permission to use their names for publicity for or to assert or imply
   endorsement of any Modified Version.

** 5. COMBINING DOCUMENTS

   You may combine the Document with other documents released under this
   License, under the terms defined in section 4 above for modified versions,
   provided that you include in the combination all of the Invariant Sections
   of all of the original documents, unmodified, and list them all as
   Invariant Sections of your combined work in its license notice, and that
   you preserve all their Warranty Disclaimers.

   The combined work need only contain one copy of this License, and multiple
   identical Invariant Sections may be replaced with a single copy. If there
   are multiple Invariant Sections with the same name but different contents,
   make the title of each such section unique by adding at the end of it, in
   parentheses, the name of the original author or publisher of that section
   if known, or else a unique number. Make the same adjustment to the
   section titles in the list of Invariant Sections in the license notice of
   the combined work.

   In the combination, you must combine any sections Entitled "History" in
   the various original documents, forming one section Entitled "History";
   likewise combine any sections Entitled "Acknowledgements", and any
   sections Entitled "Dedications". You must delete all sections Entitled
   "Endorsements".

** 6. COLLECTIONS OF DOCUMENTS

   You may make a collection consisting of the Document and other documents
   released under this License, and replace the individual copies of this
   License in the various documents with a single copy that is included in
   the collection, provided that you follow the rules of this License for
   verbatim copying of each of the documents in all other respects.

   You may extract a single document from such a collection, and distribute
   it individually under this License, provided you insert a copy of this
   License into the extracted document, and follow this License in all other
   respects regarding verbatim copying of that document.

** 7. AGGREGATION WITH INDEPENDENT WORKS

   A compilation of the Document or its derivatives with other separate and
   independent documents or works, in or on a volume of a storage or
   distribution medium, is called an "aggregate" if the copyright resulting
   from the compilation is not used to limit the legal rights of the
   compilation's users beyond what the individual works permit. When the
   Document is included in an aggregate, this License does not apply to the
   other works in the aggregate which are not themselves derivative works of
   the Document.

   If the Cover Text requirement of section 3 is applicable to these copies
   of the Document, then if the Document is less than one half of the entire
   aggregate, the Document's Cover Texts may be placed on covers that bracket
   the Document within the aggregate, or the electronic equivalent of covers
   if the Document is in electronic form. Otherwise they must appear on
   printed covers that bracket the whole aggregate.

** 8. TRANSLATION

   Translation is considered a kind of modification, so you may distribute
   translations of the Document under the terms of section 4. Replacing
   Invariant Sections with translations requires special permission from
   their copyright holders, but you may include translations of some or all
   Invariant Sections in addition to the original versions of these Invariant
   Sections. You may include a translation of this License, and all the
   license notices in the Document, and any Warranty Disclaimers, provided
   that you also include the original English version of this License and the
   original versions of those notices and disclaimers. In case of a
   disagreement between the translation and the original version of this
   License or a notice or disclaimer, the original version will prevail.

   If a section in the Document is Entitled "Acknowledgements",
   "Dedications", or "History", the requirement (section 4) to Preserve its
   Title (section 1) will typically require changing the actual title.

** 9. TERMINATION

   You may not copy, modify, sublicense, or distribute the Document except as
   expressly provided under this License. Any attempt otherwise to copy,
   modify, sublicense, or distribute it is void, and will automatically
   terminate your rights under this License.

   However, if you cease all violation of this License, then your license
   from a particular copyright holder is reinstated (a) provisionally, unless
   and until the copyright holder explicitly and finally terminates your
   license, and (b) permanently, if the copyright holder fails to notify you
   of the violation by some reasonable means prior to 60 days after the
   cessation.

   Moreover, your license from a particular copyright holder is reinstated
   permanently if the copyright holder notifies you of the violation by some
   reasonable means, this is the first time you have received notice of
   violation of this License (for any work) from that copyright holder, and
   you cure the violation prior to 30 days after your receipt of the notice.

   Termination of your rights under this section does not terminate the
   licenses of parties who have received copies or rights from you under this
   License. If your rights have been terminated and not permanently
   reinstated, receipt of a copy of some or all of the same material does not
   give you any rights to use it.

** 10. FUTURE REVISIONS OF THIS LICENSE

   The Free Software Foundation may publish new, revised versions of the GNU
   Free Documentation License from time to time. Such new versions will be
   similar in spirit to the present version, but may differ in detail to
   address new problems or concerns. See @l(http://www.gnu.org/copyleft/).

   Each version of the License is given a distinguishing version number. If
   the Document specifies that a particular numbered version of this License
   "or any later version" applies to it, you have the option of following the
   terms and conditions either of that specified version or of any later
   version that has been published (not as a draft) by the Free Software
   Foundation. If the Document does not specify a version number of this
   License, you may choose any version ever published (not as a draft) by the
   Free Software Foundation. If the Document specifies that a proxy can
   decide which future versions of this License can be used, that proxy's
   public statement of acceptance of a version permanently authorizes you to
   choose that version for the Document.

** 11. RELICENSING

   "Massive Multiauthor Collaboration Site" (or "MMC Site") means any World
   Wide Web server that publishes copyrightable works and also provides
   prominent facilities for anybody to edit those works. A public wiki that
   anybody can edit is an example of such a server. A "Massive Multiauthor
   Collaboration" (or "MMC") contained in the site means any set of
   copyrightable works thus published on the MMC site.

   "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 license
   published by Creative Commons Corporation, a not-for-profit corporation
   with a principal place of business in San Francisco, California, as well
   as future copyleft versions of that license published by that same
   organization.

   "Incorporate" means to publish or republish a Document, in whole or in
   part, as part of another Document.

   An MMC is "eligible for relicensing" if it is licensed under this License,
   and if all works that were first published under this License somewhere
   other than this MMC, and subsequently incorporated in whole or in part
   into the MMC, (1) had no cover texts or invariant sections, and (2) were
   thus incorporated prior to November 1, 2008.

   The operator of an MMC Site may republish an MMC contained in the site
   under CC-BY-SA on the same site at any time before August 1, 2009,
   provided the MMC is eligible for relicensing.

* ADDENDUM: How to use this License for your documents

  To use this License in a document you have written, include a copy of the
  License in the document and put the following copyright and license notices
  just after the title page:

  ..pre >
    Copyright (c)  YEAR  YOUR NAME.
    Permission is granted to copy, distribute and/or modify this document
    under the terms of the GNU Free Documentation License, Version 1.3
    or any later version published by the Free Software Foundation;
    with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
    A copy of the license is included in the section entitled "GNU
    Free Documentation License".
  < pre..

  If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
  replace the "with...Texts." line with this:

  ..pre >
    with the Invariant Sections being LIST THEIR TITLES, with the
    Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
  < pre..

  If you have Invariant Sections without Cover Texts, or some other
  combination of the three, merge those two alternatives to suit the
  situation.

  If your document contains nontrivial examples of program code, we recommend
  releasing these examples in parallel under your choice of free software
  license, such as the GNU General Public License, to permit their use in
  free software.

** Acerca del Autor

   Robert J. Chassell ha trabajado con GNU Emacs desde 1985. Él escribe, edita y
   enseña Emacs y Emacs Lisp, y habla en todo el mundo sobre la libertad del
   software. Chassell fue Director fundador y Tesorero de la Free Software
   Foundation, Inc. Es coautor del manual @q(Texinfo) y ha editado mas de una
   docena de libros.  Se graduó en la Universidad de Cambridge, en Inglaterra.
   Tiene un interés permanente en historia económica y social y vuela su propio
   aeroplano

* footnotes

 :: @N{1} :: El apóstrofo o comilla es una abreviación para la función
    @c{quote}; no es necesario pensar en las funciones ahora; las funciones
    se definen en la Seccion @l{#Generar un mensaje de error}.

 :: @N{2} :: Es curioso seguir el camino por el que la palabra ‘argumento’ llego
    a tener dos significados distintos, uno en matemáticas y otro en el inglés
    cotidiano. De acuerdo al @e{Oxford English Dictionary}, la palabra deriva
    del Latín para @'{dejar claro, probar}; asi llego a significar, por un hilo
    de derivación, ‘la evidencia ofrecida como prueba’, es decir ‘la informacion
    que se ofrece’, lo que conduce a su significado en Lisp. Pero en el otro hilo
    de la derivación, paso a significar ‘afirmar de una manera contra la cual
    otros pueden hacer afirmaciones contrarias’, lo que llevó al significado de
    la palabra como disputa. (Notese aqui que la palabra Inglésa tiene dos
    definiciones distintas al mismo tiempo. En contraste, en Emacs Lisp, un
    símbolo no puede tener dos definiciones de funcion diferentes al mismo
    tiempo.)

 :: @N{3} :: @c{(quote hola)} es una expansión de la abreviatura @c{'hola}.

 :: @N{4} :: En realidad, se puede utilizar @c{%s} para imprimir un número. No
    es específico. @c{%d} solo imprime la parte de un número a la izquierda
    del punto decimal, excluyendo cualquier cosa que no sea un número.

 :: @N{5} :: De hecho, por defecto, si el búfer desde el que acabas de
    cambiar es visible por tí en otra ventana, @c{other-buffer} elegirá el
    búfer más reciente que no puedas ver; esta es una sutileza que a menudo
    olvido.

 :: @N{6} :: O mejor dicho, para evitar escribir, probablemente solo necesites
    pulsar @k{RET} si @f{*scratch*} es el buffer por defecto, de ser
    diferente, solo escribe parte del nombre, por ejemplo @c{*sc}, luego
    presiona la tecla @k{TAB} para hacer que se expanda el nombre completo, y
    finalmente pulsa @k{RET}.

 :: @N{7} :: Recuerda, esta expresión te desplaza al buffer diferente más
    reciente que no puedas ver. Si realmente quieres ir al ultimo búfer
    seleccionado, incluso si es visible, es necesario evaluar la siguiente
    expresión más compleja:

    ..src > elisp
      (switch-to-buffer (other-buffer (current-buffer) t))
    < src..

    En este caso, el primer argumento de @c{other-buffer} le dice a que búfer
    saltar––el actual––y el segundo argumento @c{other-buffer} le indica que
    esta BIEN cambiar a un búfer visible. La utilidad de @c{switch-to-buffer} es
    llevarte a una ventana invisible ya que probablemente usarias
    @k{C-x o} @%c(other-window) para ir a otro búfer visible.

 :: @N{8} :: Segun Jared Diamond en @e{Guns, Germs, and Steel}, “…
    las cebras se vuelven increiblemente peligrosas a medida que envejecen”
    pero la afirmacion aquí es que no se vuelven feroces como un tigre. (1997,
    W. W. Norton and Co., ISBN 0-393-03894-2, pagina 171)

 :: @N{9} :: Actualmente, se puede aplicar @c{cons} a un elemento y un átomo
    para producir a par punteado. Los pares punteados no se discuten aquí;
    Consulta la Seccion @l{elisp.html#Dotted
    Pair Notation<>Dotted Pair Notation} en @e(El Manual de Referencia de GNU
    Emacs Lisp).

 :: @N{10} :: Más precisamente, y requiriendo un conocimiento más experto para
    entenderlo, los dos enteros son del tipo ‘Lisp_Object’, que también puede
    ser una unión C en lugar de un tipo entero.

 :: @N{11} :: Puedes escribir funciones recursivas para que sean frugales o
    derrochen recursos mentales o computacionales; como sucede, los métodos que
    la gente encuentra fáciles––que son frugales de ‘recursos mentales’––algunas
    veces usan considerables recursos del computador. Emacs fué diseñado para
    ejecutarse en máquinas que ahora consideramos limitadas y su configuracion
    por defecto es conservadora. Es posible que desees incrementar los valores de
    @c{max-specdl-size} y @c{max-lisp-eval-depth}. En mi fichero @f{.emacs}, yo
    los asigno a 15 o 30 veces su valor predeterminado.

 :: @N{12} :: La frase @:{recursion de cola} se utiliza para describir tal
    proceso, uno que usa ‘espacio constante’.

 :: @N{13} :: La jerga es ligeramente confusa: @c{triangulo-recursivo-auxiliar}
    usa un proceso que es iterativo en un procedimiento que es recursivo. El
    proceso se llama iterativo porque el ordenador solo necesita registrar los tres
    valores, @c{suma}, @c{contador}, y @c{número}: el procedimiento es recursivo
    porque la función ‘se llama a sí misma’. Por otra parte, tanto el proceso
    como el procedimiento usado por @c{triangulo-recursivo} se denominan
    recursivos. La palabra ‘recursivo’ tiene significados diferentes en los dos
    contextos.

 :: @N{14} :: Se puede añadir @f{.el} a @f{~/.emacs} y llamarlo
    @f{~/.emacs.el}. En el pasado, se prohibia escribir los atajos de
    teclado extra que el nombre @f{~/.emacs.el} requiere, pero ahora
    se puede hacer. El nuevo formato es consistente con las conveniciones de nombres
    de ficheros Emacs Lisp; el viejo formato mantiene la escritura.

 :: @N{15} :: Cuando inicio instancias de Emacs que no cargan mi
    fichero @f{.emacs} o cualquier fichero, también desactivo
    el parpadeo:

    ..srci > sh
      > emacs -q --no-site-file -eval '(blink-cursor-mode nil)'
    < srci..

    O tambien usando un conjunto más sofisticado de opciones,

    ..srci > sh
      > emacs -Q -D
    < srci..

 :: @N{16} :: También ejecuto gestores de ventanas más modernos,
    como Enlightenment, Gnome, o KDE; en esos casos, a menudo
    especifico una imagen en lugar de un color plano.
